mirror of
https://github.com/matrix-construct/construct
synced 2025-01-13 08:23:56 +01:00
ircd/modules: Preliminary matrix scaffold.
This commit is contained in:
parent
a57070a9cf
commit
a3117391b5
28 changed files with 1892 additions and 500 deletions
42
include/ircd/m.h
Normal file
42
include/ircd/m.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* charybdis: 21st Century IRC++d
|
||||
*
|
||||
* Copyright (C) 2016 Charybdis Development Team
|
||||
* Copyright (C) 2016 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#define HAVE_IRCD_M_H
|
||||
|
||||
namespace ircd {
|
||||
namespace m {
|
||||
|
||||
} // namespace m
|
||||
} // namespace ircd
|
||||
|
||||
#include "m/error.h"
|
||||
#include "m/id.h"
|
||||
#include "m/event.h"
|
||||
#include "m/request.h"
|
||||
#include "m/session.h"
|
||||
|
||||
namespace ircd {
|
||||
|
||||
} // namespace ircd
|
84
include/ircd/m/error.h
Normal file
84
include/ircd/m/error.h
Normal file
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* charybdis: 21st Century IRC++d
|
||||
*
|
||||
* Copyright (C) 2016 Charybdis Development Team
|
||||
* Copyright (C) 2016 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#define HAVE_IRCD_M_ERROR_H
|
||||
|
||||
namespace ircd {
|
||||
namespace m {
|
||||
|
||||
struct error
|
||||
:http::error
|
||||
{
|
||||
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&&...);
|
||||
error(const http::code &, const json::doc &doc = {});
|
||||
error(const http::code &, const json::obj &obj);
|
||||
};
|
||||
|
||||
} // namespace m
|
||||
} // namespace ircd
|
||||
|
||||
inline
|
||||
ircd::m::error::error(const http::code &c,
|
||||
const json::obj &obj)
|
||||
:http::error{c, std::string{obj}}
|
||||
{}
|
||||
|
||||
inline
|
||||
ircd::m::error::error(const http::code &c,
|
||||
const json::doc &doc)
|
||||
:http::error{c, std::string{doc}}
|
||||
{}
|
||||
|
||||
template<class... args>
|
||||
ircd::m::error::error(const string_view &errcode,
|
||||
const char *const &fmt,
|
||||
args&&... a)
|
||||
:error
|
||||
{
|
||||
http::BAD_REQUEST, errcode, fmt, std::forward<args>(a)...
|
||||
}{}
|
||||
|
||||
template<class... args>
|
||||
ircd::m::error::error(const http::code &status,
|
||||
const string_view &errcode,
|
||||
const char *const &fmt,
|
||||
args&&... a)
|
||||
:http::error
|
||||
{
|
||||
status, [&]() -> std::string
|
||||
{
|
||||
char estr[256]; const auto estr_len
|
||||
{
|
||||
fmt::snprintf{estr, sizeof(estr), fmt, std::forward<args>(a)...}
|
||||
};
|
||||
|
||||
return json::obj
|
||||
{
|
||||
{ "errcode", errcode },
|
||||
{ "error", string_view(estr, estr_len) }
|
||||
};
|
||||
}()
|
||||
}{}
|
89
include/ircd/m/event.h
Normal file
89
include/ircd/m/event.h
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* charybdis: 21st Century IRC++d
|
||||
*
|
||||
* Copyright (C) 2016 Charybdis Development Team
|
||||
* Copyright (C) 2016 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ircd/json/object.h>
|
||||
|
||||
#pragma once
|
||||
#define HAVE_IRCD_M_EVENT_H
|
||||
|
||||
namespace ircd {
|
||||
namespace m {
|
||||
|
||||
struct event
|
||||
:json::object
|
||||
<
|
||||
string_view,
|
||||
time_t,
|
||||
string_view,
|
||||
string_view,
|
||||
string_view,
|
||||
string_view
|
||||
>
|
||||
{
|
||||
IRCD_MEMBERS
|
||||
(
|
||||
"content",
|
||||
"origin_server_ts",
|
||||
"sender",
|
||||
"type",
|
||||
"unsigned",
|
||||
"state_key"
|
||||
)
|
||||
|
||||
template<class... A>
|
||||
event(A&&... a)
|
||||
:object{std::make_tuple(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)...)}
|
||||
{}
|
||||
};
|
||||
|
||||
} // namespace m
|
||||
} // namespace ircd
|
102
include/ircd/m/id.h
Normal file
102
include/ircd/m/id.h
Normal file
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* charybdis: 21st Century IRC++d
|
||||
*
|
||||
* Copyright (C) 2016 Charybdis Development Team
|
||||
* Copyright (C) 2016 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#define HAVE_IRCD_M_ID_H
|
||||
|
||||
namespace ircd {
|
||||
namespace m {
|
||||
|
||||
const size_t USER_ID_BUFSIZE = 256;
|
||||
const size_t ACCESS_TOKEN_BUFSIZE = 256;
|
||||
|
||||
inline bool
|
||||
username_valid(const string_view &username)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool
|
||||
mxid_valid(const string_view &mxid)
|
||||
{
|
||||
const auto userhost(split(mxid, ':'));
|
||||
const auto &user(userhost.first);
|
||||
const auto &host(userhost.second);
|
||||
if(user.empty() || host.empty())
|
||||
return false;
|
||||
|
||||
if(!startswith(user, '@') || user.size() == 1)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline string_view
|
||||
username_generate(char *const &buf,
|
||||
const size_t &max)
|
||||
{
|
||||
const uint32_t num(rand() % 100000U);
|
||||
const size_t len(snprintf(buf, max, "@guest%u", num));
|
||||
return { buf, len };
|
||||
}
|
||||
|
||||
inline string_view
|
||||
access_token_generate(char *const &buf,
|
||||
const size_t &max)
|
||||
{
|
||||
const int num[] { rand(), rand(), rand() };
|
||||
const size_t len(snprintf(buf, max, "charybdis%d%d%d", num[0], num[1], num[2]));
|
||||
return { buf, len };
|
||||
}
|
||||
|
||||
struct id
|
||||
{
|
||||
string_view user;
|
||||
string_view host;
|
||||
|
||||
template<size_t size>
|
||||
id(string_view user, string_view host)
|
||||
:user{std::move(user)}
|
||||
,host{std::move(host)}
|
||||
{}
|
||||
|
||||
id(const string_view &user, const string_view &host, char *const &buf, const size_t &max)
|
||||
:user{user}
|
||||
,host{host}
|
||||
{
|
||||
char gen_buf[USER_ID_BUFSIZE];
|
||||
fmt::snprintf(buf, max, "%s%s:%s",
|
||||
user.empty() || startswith(user, '@')? "" : "@",
|
||||
!user.empty()? user : username_generate(gen_buf, sizeof(gen_buf)),
|
||||
host);
|
||||
}
|
||||
|
||||
template<size_t size>
|
||||
id(const string_view &user, const string_view &host, char (&buf)[size])
|
||||
:id{user, host, buf, size}
|
||||
{}
|
||||
};
|
||||
|
||||
} // namespace m
|
||||
} // namespace ircd
|
75
include/ircd/m/request.h
Normal file
75
include/ircd/m/request.h
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* charybdis: 21st Century IRC++d
|
||||
*
|
||||
* Copyright (C) 2016 Charybdis Development Team
|
||||
* Copyright (C) 2016 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#define HAVE_IRCD_M_REQUEST_H
|
||||
|
||||
namespace ircd {
|
||||
namespace m {
|
||||
|
||||
struct request
|
||||
:json::obj
|
||||
{
|
||||
string_view method;
|
||||
string_view path;
|
||||
string_view query;
|
||||
string_view access_token;
|
||||
|
||||
request(const string_view &method,
|
||||
const string_view &path,
|
||||
const string_view &query = {},
|
||||
std::initializer_list<json::obj::member> body = {});
|
||||
|
||||
request(const string_view &method,
|
||||
const string_view &path,
|
||||
const string_view &query,
|
||||
const json::doc &content);
|
||||
};
|
||||
|
||||
} // namespace m
|
||||
} // namespace ircd
|
||||
|
||||
inline
|
||||
ircd::m::request::request(const string_view &method,
|
||||
const string_view &path,
|
||||
const string_view &query,
|
||||
std::initializer_list<json::obj::member> body)
|
||||
:json::obj{std::move(body)}
|
||||
,method{method}
|
||||
,path{path}
|
||||
,query{query}
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
ircd::m::request::request(const string_view &method,
|
||||
const string_view &path,
|
||||
const string_view &query,
|
||||
const json::doc &content)
|
||||
:json::obj{content}
|
||||
,method{method}
|
||||
,path{path}
|
||||
,query{query}
|
||||
{
|
||||
}
|
44
include/ircd/m/session.h
Normal file
44
include/ircd/m/session.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* charybdis: 21st Century IRC++d
|
||||
*
|
||||
* Copyright (C) 2016 Charybdis Development Team
|
||||
* Copyright (C) 2016 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#define HAVE_IRCD_M_SESSION_H
|
||||
|
||||
namespace ircd {
|
||||
namespace m {
|
||||
|
||||
struct session
|
||||
:client
|
||||
{
|
||||
std::string access_token;
|
||||
std::deque<std::string> tape;
|
||||
std::multimap<string_view, string_view> resource;
|
||||
|
||||
json::doc operator()(parse::buffer &pb, request &);
|
||||
|
||||
session(const host_port &);
|
||||
};
|
||||
|
||||
} // namespace m
|
||||
} // namespace ircd
|
|
@ -1,239 +0,0 @@
|
|||
/*
|
||||
* charybdis: 21st Century IRC++d
|
||||
*
|
||||
* Copyright (C) 2016 Charybdis Development Team
|
||||
* Copyright (C) 2016 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#define HAVE_IRCD_MATRIX_H
|
||||
|
||||
namespace ircd {
|
||||
namespace m {
|
||||
|
||||
struct error
|
||||
:http::error
|
||||
{
|
||||
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&&...);
|
||||
error(const http::code &, const json::doc &doc = {});
|
||||
error(const http::code &, const json::obj &obj);
|
||||
};
|
||||
|
||||
struct member
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
template<const char *const &name>
|
||||
struct mem
|
||||
:member
|
||||
{
|
||||
std::string value;
|
||||
|
||||
operator const std::string &() const { return value; }
|
||||
|
||||
mem(const json::obj &obj)
|
||||
:value{obj[name]}
|
||||
{}
|
||||
|
||||
mem(const json::doc &doc)
|
||||
:value{doc[name]}
|
||||
{}
|
||||
|
||||
mem() = default;
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &s, const mem &m)
|
||||
{
|
||||
s << m.value;
|
||||
return s;
|
||||
}
|
||||
};
|
||||
|
||||
struct session
|
||||
{
|
||||
static constexpr auto _user_id { "user_id" };
|
||||
static constexpr auto _access_token { "access_token" };
|
||||
static constexpr auto _home_server { "home_server" };
|
||||
static constexpr auto _device_id { "device_id" };
|
||||
|
||||
mem<_user_id> user_id;
|
||||
mem<_access_token> access_token;
|
||||
mem<_home_server> home_server;
|
||||
mem<_device_id> device_id;
|
||||
|
||||
session(const json::obj &obj)
|
||||
:user_id{obj}
|
||||
,access_token{obj}
|
||||
,home_server{obj}
|
||||
,device_id{obj}
|
||||
{}
|
||||
|
||||
session() = default;
|
||||
};
|
||||
|
||||
struct request
|
||||
:json::obj
|
||||
{
|
||||
struct quote;
|
||||
struct versions;
|
||||
struct sync;
|
||||
struct login;
|
||||
|
||||
string_view method;
|
||||
string_view resource;
|
||||
string_view access_token;
|
||||
|
||||
request(const string_view &method,
|
||||
const string_view &resource,
|
||||
std::initializer_list<json::obj::member> body = {})
|
||||
:json::obj{std::move(body)}
|
||||
,method{method}
|
||||
,resource{resource}
|
||||
{}
|
||||
|
||||
request(const string_view &method,
|
||||
const string_view &resource,
|
||||
const json::doc &content)
|
||||
:json::obj{content}
|
||||
,method{method}
|
||||
,resource{resource}
|
||||
{}
|
||||
};
|
||||
|
||||
struct request::sync
|
||||
:request
|
||||
{
|
||||
/*
|
||||
bool full_state;
|
||||
string_view since;
|
||||
string_view filter;
|
||||
string_view set_presence;
|
||||
milliseconds timeout;
|
||||
*/
|
||||
|
||||
sync(std::initializer_list<json::obj::member> body = {})
|
||||
:request{"GET", "/_matrix/client/r0/sync", std::move(body)}
|
||||
{}
|
||||
};
|
||||
|
||||
struct request::login
|
||||
:request
|
||||
{
|
||||
/*
|
||||
string_view user;
|
||||
string_view password;
|
||||
*/
|
||||
|
||||
login(std::initializer_list<json::obj::member> body = {})
|
||||
:request{"POST", "/_matrix/client/r0/login", std::move(body)}
|
||||
{}
|
||||
};
|
||||
|
||||
struct request::quote
|
||||
:request
|
||||
{
|
||||
quote(const string_view &method,
|
||||
const string_view &resource,
|
||||
const json::doc &content)
|
||||
:request{method, resource, content}
|
||||
{}
|
||||
};
|
||||
|
||||
struct client
|
||||
:ircd::client
|
||||
{
|
||||
IRCD_EXCEPTION(ircd::error, error)
|
||||
|
||||
std::unique_ptr<session> sess;
|
||||
|
||||
// Synchronize server state
|
||||
void sync(request::sync &r);
|
||||
|
||||
// Account login
|
||||
session login(request::login &);
|
||||
|
||||
// Account registration
|
||||
void reg(const string_view &user,
|
||||
const string_view &pass,
|
||||
const string_view &type = "m.login.dummy");
|
||||
|
||||
void quote(request::quote &);
|
||||
|
||||
client(const host_port &);
|
||||
};
|
||||
|
||||
using doc_closure = std::function<void (const json::doc &)>;
|
||||
using arr_closure = std::function<void (const json::arr &)>;
|
||||
|
||||
struct request::versions
|
||||
:request
|
||||
{
|
||||
versions(client &, const doc_closure & = nullptr, std::initializer_list<json::obj::member> body = {});
|
||||
};
|
||||
|
||||
} // namespace m
|
||||
} // namespace ircd
|
||||
|
||||
inline
|
||||
ircd::m::error::error(const http::code &c,
|
||||
const json::obj &obj)
|
||||
:http::error{c, std::string{obj}}
|
||||
{}
|
||||
|
||||
inline
|
||||
ircd::m::error::error(const http::code &c,
|
||||
const json::doc &doc)
|
||||
:http::error{c, std::string{doc}}
|
||||
{}
|
||||
|
||||
template<class... args>
|
||||
ircd::m::error::error(const string_view &errcode,
|
||||
const char *const &fmt,
|
||||
args&&... a)
|
||||
:error
|
||||
{
|
||||
http::BAD_REQUEST, errcode, fmt, std::forward<args>(a)...
|
||||
}{}
|
||||
|
||||
template<class... args>
|
||||
ircd::m::error::error(const http::code &status,
|
||||
const string_view &errcode,
|
||||
const char *const &fmt,
|
||||
args&&... a)
|
||||
:http::error
|
||||
{
|
||||
status, [&]
|
||||
{
|
||||
char estr[256]; const auto estr_len
|
||||
{
|
||||
fmt::snprintf(estr, sizeof(estr), fmt, std::forward<args>(a)...)
|
||||
};
|
||||
|
||||
return std::string
|
||||
{
|
||||
json::obj
|
||||
{
|
||||
{ "errcode", errcode },
|
||||
{ "error", string_view(estr, estr_len) }
|
||||
}
|
||||
};
|
||||
}()
|
||||
}{}
|
|
@ -182,4 +182,3 @@ struct line {};
|
|||
#include "js.h"
|
||||
#include "client.h"
|
||||
#include "mods.h"
|
||||
#include "matrix.h"
|
||||
|
|
239
ircd/matrix.cc
239
ircd/matrix.cc
|
@ -19,231 +19,50 @@
|
|||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
namespace ircd {
|
||||
namespace m {
|
||||
#include <ircd/m.h>
|
||||
|
||||
db::handle accounts;
|
||||
|
||||
} // namespace m
|
||||
} // namespace ircd
|
||||
|
||||
ircd::m::client::client(const host_port &host_port)
|
||||
:ircd::client{host_port}
|
||||
ircd::m::session::session(const host_port &host_port)
|
||||
:client{host_port}
|
||||
{
|
||||
}
|
||||
|
||||
ircd::m::request::versions::versions(client &client,
|
||||
const doc_closure &closure,
|
||||
std::initializer_list<json::obj::member> body)
|
||||
:request
|
||||
ircd::json::doc
|
||||
ircd::m::session::operator()(parse::buffer &pb,
|
||||
request &r)
|
||||
{
|
||||
"GET", "/_matrix/client/versions", std::move(body)
|
||||
}
|
||||
{
|
||||
const auto handle([&](const http::code &code,
|
||||
const json::doc &doc)
|
||||
parse::capstan pc
|
||||
{
|
||||
switch(code)
|
||||
{
|
||||
case http::OK:
|
||||
if(closure)
|
||||
closure(doc);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
throw m::error(code, doc);
|
||||
}
|
||||
});
|
||||
|
||||
char buf[1024];
|
||||
parse::buffer pb{buf};
|
||||
parse::capstan pc{pb, read_closure(client)};
|
||||
const auto handler([&pc, &handle]
|
||||
(const http::response::head &head)
|
||||
{
|
||||
const http::response::content content{pc, head};
|
||||
const auto status(http::status(head.status));
|
||||
const json::doc doc{content};
|
||||
handle(status, doc);
|
||||
});
|
||||
pb, read_closure(*this)
|
||||
};
|
||||
|
||||
http::request
|
||||
{
|
||||
host(remote_addr(client)), method, resource, std::string(*this), write_closure(client),
|
||||
host(remote_addr(*this)),
|
||||
r.method,
|
||||
r.path,
|
||||
r.query,
|
||||
std::string(r),
|
||||
write_closure(*this),
|
||||
{
|
||||
{ "Content-Type"s, "application/json"s }
|
||||
}
|
||||
};
|
||||
|
||||
http::code status;
|
||||
json::doc doc;
|
||||
http::response
|
||||
{
|
||||
pc, nullptr, handler
|
||||
pc,
|
||||
nullptr,
|
||||
[&pc, &status, &doc](const http::response::head &head)
|
||||
{
|
||||
status = http::status(head.status);
|
||||
doc = http::response::content{pc, head};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
ircd::m::client::reg(const string_view &user,
|
||||
const string_view &pass,
|
||||
const string_view &type)
|
||||
{
|
||||
const json::obj auth
|
||||
{
|
||||
{ "type", type }
|
||||
};
|
||||
|
||||
const json::obj obj
|
||||
{
|
||||
{ "password", pass },
|
||||
{ "username", user },
|
||||
{ "auth", &auth },
|
||||
};
|
||||
|
||||
const auto handle([&](const http::code &code,
|
||||
const json::doc &doc)
|
||||
{
|
||||
switch(code)
|
||||
{
|
||||
case http::OK:
|
||||
std::cout << "OK!" << std::endl;
|
||||
std::cout << doc << std::endl;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw m::error(code, doc);
|
||||
}
|
||||
});
|
||||
|
||||
char buf[4096];
|
||||
parse::buffer pb{buf};
|
||||
parse::capstan pc{pb, read_closure(*this)};
|
||||
const auto handler([&pc, &handle]
|
||||
(const http::response::head &head)
|
||||
{
|
||||
const http::response::content content{pc, head};
|
||||
const auto status(http::status(head.status));
|
||||
const json::doc doc{content};
|
||||
handle(status, doc);
|
||||
});
|
||||
|
||||
http::request
|
||||
{
|
||||
host(remote_addr(*this)), "POST"s, "/_matrix/client/r0/register"s, std::string(obj), write_closure(*this),
|
||||
{
|
||||
{ "Content-Type"s, "application/json"s }
|
||||
}
|
||||
};
|
||||
|
||||
http::response
|
||||
{
|
||||
pc, nullptr, handler
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
ircd::m::session
|
||||
ircd::m::client::login(request::login &r)
|
||||
{
|
||||
session ret;
|
||||
|
||||
const auto handle([&](const http::code &code,
|
||||
const json::doc &doc)
|
||||
{
|
||||
switch(code)
|
||||
{
|
||||
case http::OK:
|
||||
ret = json::obj{doc};
|
||||
this->sess.reset(new session{doc});
|
||||
break;
|
||||
|
||||
default:
|
||||
throw m::error(code, doc);
|
||||
}
|
||||
});
|
||||
|
||||
char buf[4096];
|
||||
parse::buffer pb{buf};
|
||||
parse::capstan pc{pb, read_closure(*this)};
|
||||
const auto handler([&pc, &handle]
|
||||
(const http::response::head &head)
|
||||
{
|
||||
const http::response::content content{pc, head};
|
||||
const auto status(http::status(head.status));
|
||||
const json::doc doc{content};
|
||||
handle(status, doc);
|
||||
});
|
||||
|
||||
http::request
|
||||
{
|
||||
host(remote_addr(*this)), r.method, r.resource, std::string(r), write_closure(*this),
|
||||
{
|
||||
{ "Content-Type"s, "application/json"s }
|
||||
}
|
||||
};
|
||||
|
||||
http::response
|
||||
{
|
||||
pc, nullptr, handler
|
||||
};
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
ircd::m::client::sync(request::sync &r)
|
||||
{
|
||||
if(!sess)
|
||||
throw error("No active session");
|
||||
|
||||
static const auto urlfmt
|
||||
{
|
||||
"%s?access_token=%s"
|
||||
};
|
||||
|
||||
char url[1024]; const auto urllen
|
||||
{
|
||||
fmt::snprintf(url, sizeof(url), urlfmt, r.resource, string(sess->access_token))
|
||||
};
|
||||
|
||||
http::request
|
||||
{
|
||||
host(remote_addr(*this)), r.method, url, {}, write_closure(*this),
|
||||
{
|
||||
{ "Content-Type"s, "application/json"s }
|
||||
}
|
||||
};
|
||||
|
||||
char buf[4096];
|
||||
parse::buffer pb{buf};
|
||||
parse::capstan pc{pb, read_closure(*this)};
|
||||
http::response
|
||||
{
|
||||
pc, nullptr, [this, &pc](const auto &head)
|
||||
{
|
||||
http::response::content content
|
||||
{
|
||||
pc, head
|
||||
};
|
||||
|
||||
switch(http::status(head.status))
|
||||
{
|
||||
case http::OK:
|
||||
{
|
||||
const json::obj d(content, true);
|
||||
const json::arr a(d["account_data.events[0]"]);
|
||||
std::cout << a << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
throw m::error(http::status(head.status), json::doc(content));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
ircd::m::client::quote(request::quote &r)
|
||||
{
|
||||
|
||||
if(status < 200 || status >= 300)
|
||||
throw m::error(status, doc);
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <ircd/m.h>
|
||||
|
||||
namespace ircd {
|
||||
|
||||
IRCD_INIT_PRIORITY(STD_CONTAINER)
|
||||
|
|
|
@ -28,13 +28,35 @@ AM_LDFLAGS += \
|
|||
# This puts the source in client/ but the installed
|
||||
# library is client_X.so in the main modules dir.
|
||||
client_moduledir=@moduledir@
|
||||
client_client_versions_la_SOURCES = client/versions.cc
|
||||
client_client_register_la_SOURCES = client/register.cc
|
||||
client_client_login_la_SOURCES = client/login.cc
|
||||
client_module_LTLIBRARIES = \
|
||||
client/client_versions.la \
|
||||
client/client_register.la \
|
||||
client/client_login.la
|
||||
client_client_versions_la_SOURCES = client/versions.cc
|
||||
client_client_account_la_SOURCES = client/account.cc
|
||||
client_client_register_la_SOURCES = client/register.cc
|
||||
client_client_login_la_SOURCES = client/login.cc
|
||||
client_client_logout_la_SOURCES = client/logout.cc
|
||||
client_client_sync_la_SOURCES = client/sync.cc
|
||||
client_client_room_la_SOURCES = client/room.cc
|
||||
client_client_publicrooms_la_SOURCES = client/publicrooms.cc
|
||||
client_client_createroom_la_SOURCES = client/createroom.cc
|
||||
client_client_pushrules_la_SOURCES = client/pushrules.cc
|
||||
client_client_user_la_SOURCES = client/user.cc
|
||||
client_client_voip_turnserver_la_SOURCES = client/voip/turnserver.cc
|
||||
client_module_LTLIBRARIES = \
|
||||
client/client_versions.la \
|
||||
client/client_account.la \
|
||||
client/client_register.la \
|
||||
client/client_login.la \
|
||||
client/client_logout.la \
|
||||
client/client_sync.la \
|
||||
client/client_room.la \
|
||||
client/client_publicrooms.la \
|
||||
client/client_createroom.la \
|
||||
client/client_pushrules.la \
|
||||
client/client_user.la \
|
||||
client/client_voip_turnserver.la
|
||||
|
||||
moduledir=@moduledir@
|
||||
matrix_la_SOURCES = matrix.cc
|
||||
root_la_SOURCES = root.cc
|
||||
module_LTLIBRARIES = \
|
||||
matrix.la \
|
||||
root.la
|
||||
|
|
153
modules/client/account.cc
Normal file
153
modules/client/account.cc
Normal file
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
* 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 token_descriptor
|
||||
{
|
||||
"token",
|
||||
"An index of access_token to user_id",
|
||||
{
|
||||
// readable key // readable value
|
||||
typeid(string_view), typeid(string_view)
|
||||
}
|
||||
};
|
||||
|
||||
const database::descriptor account_registered_descriptor
|
||||
{
|
||||
"registered",
|
||||
"A UNIX epoch timestamp sampled when the account was created.",
|
||||
{
|
||||
// readable key // binary value
|
||||
typeid(string_view), typeid(time_t)
|
||||
}
|
||||
};
|
||||
|
||||
const database::description account_description
|
||||
{
|
||||
{ "default" },
|
||||
token_descriptor,
|
||||
account_registered_descriptor,
|
||||
{ "access_token" },
|
||||
{ "access_token.text" },
|
||||
{ "password" },
|
||||
{ "password.text" },
|
||||
{ "password.hash" },
|
||||
{ "password.hash.sha256" },
|
||||
};
|
||||
|
||||
std::shared_ptr<database> account_database
|
||||
{
|
||||
std::make_shared<database>("account"s, ""s, account_description)
|
||||
};
|
||||
|
||||
extern database *const account
|
||||
{
|
||||
account_database.get()
|
||||
};
|
||||
|
||||
struct account
|
||||
:resource
|
||||
{
|
||||
resource deactivate
|
||||
{
|
||||
"_matrix/client/r0/account/deactivate",
|
||||
"Deactivate the user's account, removing all ability for the user to login again. (3.3.3)"
|
||||
};
|
||||
|
||||
resource password
|
||||
{
|
||||
"_matrix/client/r0/account/password",
|
||||
"Changes the password for an account on this homeserver. (3.3.4)"
|
||||
};
|
||||
|
||||
using resource::resource;
|
||||
}
|
||||
account_resource
|
||||
{
|
||||
"_matrix/client/r0/account",
|
||||
"Account management (3.3)"
|
||||
};
|
||||
|
||||
resource::response
|
||||
account_password(client &client, const resource::request &request)
|
||||
try
|
||||
{
|
||||
const auto new_password
|
||||
{
|
||||
request.at("new_password")
|
||||
};
|
||||
|
||||
const auto type
|
||||
{
|
||||
unquote(request.at("auth.type"))
|
||||
};
|
||||
|
||||
const auto session
|
||||
{
|
||||
request["auth.session"]
|
||||
};
|
||||
|
||||
if(!type.empty() && type != "m.login.token")
|
||||
{
|
||||
throw m::error
|
||||
{
|
||||
"M_UNSUPPORTED", "Login type is not supported."
|
||||
};
|
||||
}
|
||||
|
||||
//db::handle hand(account, "foo");
|
||||
//database::snapshot snap(hand);
|
||||
|
||||
/*
|
||||
account(db::MERGE, "jzk", std::string
|
||||
{
|
||||
json::obj
|
||||
{{
|
||||
"password",
|
||||
{
|
||||
{ "plaintext", new_password }
|
||||
}
|
||||
}}
|
||||
});
|
||||
*/
|
||||
return resource::response
|
||||
{
|
||||
client
|
||||
};
|
||||
}
|
||||
catch(const db::not_found &e)
|
||||
{
|
||||
throw m::error
|
||||
{
|
||||
http::FORBIDDEN, "M_FORBIDDEN", "Access denied."
|
||||
};
|
||||
}
|
||||
|
||||
resource::method post
|
||||
{
|
||||
account_resource.password, "POST", account_password
|
||||
};
|
||||
|
||||
mapi::header IRCD_MODULE
|
||||
{
|
||||
"registers the resource 'client/login' to handle requests"
|
||||
};
|
30
modules/client/account.h
Normal file
30
modules/client/account.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> account_database
|
||||
{
|
||||
"client_account", "account_database"
|
||||
};
|
||||
|
||||
extern ircd::database *const account
|
||||
{
|
||||
account_database.get()
|
||||
};
|
88
modules/client/createroom.cc
Normal file
88
modules/client/createroom.cc
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
import<database *> room_database
|
||||
{
|
||||
"client_room", "room"
|
||||
};
|
||||
|
||||
extern database *const room
|
||||
{
|
||||
room_database
|
||||
};
|
||||
|
||||
resource createroom
|
||||
{
|
||||
"_matrix/client/r0/createRoom",
|
||||
"Create a new room with various configuration options. (7.1.1)"
|
||||
};
|
||||
|
||||
resource::response
|
||||
room_create(client &client, const resource::request &request)
|
||||
try
|
||||
{
|
||||
const auto name
|
||||
{
|
||||
unquote(request["name"])
|
||||
};
|
||||
|
||||
const auto visibility
|
||||
{
|
||||
unquote(request["visibility"])
|
||||
};
|
||||
|
||||
std::string room_id {"!foo@bar.com"};
|
||||
|
||||
return resource::response
|
||||
{
|
||||
client, http::CREATED, json::obj
|
||||
{
|
||||
{ "room_id", room_id }
|
||||
}
|
||||
};
|
||||
}
|
||||
catch(const db::not_found &e)
|
||||
{
|
||||
throw m::error
|
||||
{
|
||||
http::CONFLICT, "M_ROOM_IN_USE", "The desired room name is in use."
|
||||
};
|
||||
|
||||
throw m::error
|
||||
{
|
||||
http::CONFLICT, "M_ROOM_ALIAS_IN_USE", "An alias of the desired room is in use."
|
||||
};
|
||||
}
|
||||
|
||||
resource::method post
|
||||
{
|
||||
createroom, "POST", room_create,
|
||||
{
|
||||
post.REQUIRES_AUTH
|
||||
}
|
||||
};
|
||||
|
||||
mapi::header IRCD_MODULE
|
||||
{
|
||||
"registers the resource 'client/createRoom' to handle requests"
|
||||
};
|
|
@ -19,75 +19,132 @@
|
|||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using namespace ircd;
|
||||
#include "account.h"
|
||||
|
||||
mods::sym_ref<db::handle> accounts_ref
|
||||
{
|
||||
"client_register",
|
||||
"accounts"
|
||||
};
|
||||
using namespace ircd;
|
||||
|
||||
resource login_resource
|
||||
{
|
||||
"/_matrix/client/r0/login",
|
||||
"_matrix/client/r0/login",
|
||||
"Authenticates the user by password, and issues an access token "
|
||||
"they can use to authorize themself in subsequent requests. (3.2.2)"
|
||||
};
|
||||
|
||||
const auto home_server
|
||||
{
|
||||
// "The hostname of the homeserver on which the account has been registered."
|
||||
"cdc.z"
|
||||
};
|
||||
|
||||
using object = db::object<account>;
|
||||
template<class T = string_view> using value = db::value<T, account>;
|
||||
|
||||
resource::response
|
||||
login(client &client, const resource::request &request)
|
||||
try
|
||||
login_password(client &client, const resource::request &request)
|
||||
{
|
||||
const auto user
|
||||
{
|
||||
// "The fully qualified user ID or just local part of the user ID, to log in."
|
||||
unquote(request.at("user"))
|
||||
};
|
||||
|
||||
char user_id[m::USER_ID_BUFSIZE]; m::id
|
||||
{
|
||||
user, home_server, user_id
|
||||
};
|
||||
|
||||
const auto password
|
||||
{
|
||||
// "Required. The user's password."
|
||||
request.at("password")
|
||||
};
|
||||
|
||||
const auto type
|
||||
{
|
||||
unquote(request["type"])
|
||||
};
|
||||
|
||||
if(!type.empty() && type != "m.login.password")
|
||||
{
|
||||
value<> password_text("password.text", user_id);
|
||||
if(password_text != password)
|
||||
throw m::error
|
||||
{
|
||||
"M_UNSUPPORTED", "Login type is not supported."
|
||||
http::FORBIDDEN, "M_FORBIDDEN", "Access denied."
|
||||
};
|
||||
}
|
||||
|
||||
db::handle &accounts(accounts_ref);
|
||||
accounts(user, [&password](const json::doc &user)
|
||||
{
|
||||
if(user["password"] != password)
|
||||
throw db::not_found();
|
||||
});
|
||||
// "An access token for the account. This access token can then be used to "
|
||||
// "authorize other requests. The access token may expire at some point, and if "
|
||||
// "so, it SHOULD come with a refresh_token. There is no specific error message to "
|
||||
// "indicate that a request has failed because an access token has expired; "
|
||||
// "instead, if a client has reason to believe its access token is valid, and "
|
||||
// "it receives an auth error, they should attempt to refresh for a new token "
|
||||
// "on failure, and retry the request with the new token."
|
||||
value<> access_token_text{"access_token.text", user_id};
|
||||
|
||||
const auto access_token(123456);
|
||||
const auto home_server("cdc.z");
|
||||
const auto device_id("ABCDEF");
|
||||
// Generate access token
|
||||
char access_token[m::ACCESS_TOKEN_BUFSIZE];
|
||||
m::access_token_generate(access_token, sizeof(access_token));
|
||||
|
||||
// Write access token to database
|
||||
access_token_text = access_token;
|
||||
ircd::resource::tokens.emplace(access_token, &client); //TODO: XXX
|
||||
value<> token_to_user_id{"token", access_token_text};
|
||||
token_to_user_id = user_id;
|
||||
|
||||
// Send response to user
|
||||
return resource::response
|
||||
{
|
||||
client,
|
||||
{
|
||||
{ "user_id", user },
|
||||
{ "user_id", user_id },
|
||||
{ "access_token", access_token },
|
||||
{ "home_server", home_server },
|
||||
{ "device_id", device_id },
|
||||
}
|
||||
};
|
||||
}
|
||||
catch(const db::not_found &e)
|
||||
|
||||
resource::response
|
||||
login_token(client &client, const resource::request &request)
|
||||
{
|
||||
throw m::error
|
||||
const auto token
|
||||
{
|
||||
http::FORBIDDEN, "M_FORBIDDEN", "Access denied."
|
||||
unquote(request.at("token"))
|
||||
};
|
||||
|
||||
const value<> user_id
|
||||
{
|
||||
"token", token
|
||||
};
|
||||
|
||||
if(!user_id)
|
||||
throw m::error
|
||||
{
|
||||
http::FORBIDDEN, "M_FORBIDDEN", "Access denied."
|
||||
};
|
||||
|
||||
return resource::response
|
||||
{
|
||||
client,
|
||||
{
|
||||
{ "user_id", string_view(user_id) },
|
||||
{ "access_token", token },
|
||||
{ "home_server", home_server },
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
resource::response
|
||||
login(client &client, const resource::request &request)
|
||||
{
|
||||
const auto type
|
||||
{
|
||||
// "Required. The login type being used. Currently only "m.login.password" is supported."
|
||||
unquote(request.at("type"))
|
||||
};
|
||||
|
||||
if(type == "m.login.password")
|
||||
return login_password(client, request);
|
||||
else if(type == "m.login.token")
|
||||
return login_token(client, request);
|
||||
else
|
||||
throw m::error
|
||||
{
|
||||
"M_UNSUPPORTED", "Login type is not supported."
|
||||
};
|
||||
}
|
||||
|
||||
resource::method post
|
||||
|
|
65
modules/client/logout.cc
Normal file
65
modules/client/logout.cc
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "account.h"
|
||||
|
||||
using namespace ircd;
|
||||
|
||||
using object = db::object<account>;
|
||||
template<class T = string_view> using value = db::value<T, account>;
|
||||
|
||||
resource logout_resource
|
||||
{
|
||||
"_matrix/client/r0/logout",
|
||||
"Invalidates an existing access token, so that it can no longer be used for "
|
||||
"authorization. (3.2.3)"
|
||||
};
|
||||
|
||||
resource::response
|
||||
logout(client &client, const resource::request &request)
|
||||
{
|
||||
const auto &access_token(request.query.at("access_token"));
|
||||
const auto it(resource::tokens.find(access_token));
|
||||
if(unlikely(it == end(resource::tokens)))
|
||||
throw http::error{http::INTERNAL_SERVER_ERROR};
|
||||
|
||||
resource::tokens.erase(it);
|
||||
return resource::response
|
||||
{
|
||||
client, json::obj
|
||||
{
|
||||
{ }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
resource::method post
|
||||
{
|
||||
logout_resource, "POST", logout,
|
||||
{
|
||||
post.REQUIRES_AUTH
|
||||
}
|
||||
};
|
||||
|
||||
mapi::header IRCD_MODULE
|
||||
{
|
||||
"registers the resource 'client/logout' to handle requests"
|
||||
};
|
96
modules/client/publicrooms.cc
Normal file
96
modules/client/publicrooms.cc
Normal file
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "room.h"
|
||||
|
||||
using namespace ircd;
|
||||
|
||||
resource publicrooms_resource
|
||||
{
|
||||
"_matrix/client/r0/publicRooms",
|
||||
"Lists the public rooms on the server. "
|
||||
"This API returns paginated responses. (7.5)"
|
||||
};
|
||||
|
||||
resource::response
|
||||
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
|
||||
{
|
||||
client, json::obj
|
||||
{
|
||||
{ }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
resource::method post
|
||||
{
|
||||
publicrooms_resource, "GET", get_publicrooms
|
||||
};
|
||||
|
||||
mapi::header IRCD_MODULE
|
||||
{
|
||||
"registers the resource 'client/publicrooms' to manage Matrix rooms"
|
||||
};
|
58
modules/client/pushrules.cc
Normal file
58
modules/client/pushrules.cc
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
resource pushrules
|
||||
{
|
||||
"_matrix/client/r0/pushrules", R"(
|
||||
Retrieve all push rulesets for this user. Clients can "drill-down" on the rulesets by
|
||||
suffixing a scope to this path e.g. /pushrules/global/. This will return a subset of this data
|
||||
under the specified key e.g. the global key. (11.10.1.4.6)
|
||||
)"
|
||||
};
|
||||
|
||||
resource::response
|
||||
get_pushrules(client &client, const resource::request &request)
|
||||
try
|
||||
{
|
||||
return resource::response
|
||||
{
|
||||
client, json::obj
|
||||
{
|
||||
{ }
|
||||
}
|
||||
};
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
resource::method get
|
||||
{
|
||||
pushrules, "GET", get_pushrules
|
||||
};
|
||||
|
||||
mapi::header IRCD_MODULE
|
||||
{
|
||||
"registers the resource 'client/pushrules' to handle requests"
|
||||
};
|
|
@ -19,37 +19,145 @@
|
|||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "account.h"
|
||||
|
||||
using namespace ircd;
|
||||
|
||||
db::handle accounts
|
||||
using object = db::object<account>;
|
||||
template<class T = string_view> using value = db::value<T, account>;
|
||||
|
||||
const auto home_server
|
||||
{
|
||||
"accounts"
|
||||
// "The hostname of the homeserver on which the account has been registered."
|
||||
"cdc.z"
|
||||
};
|
||||
|
||||
resource::response
|
||||
handle_post(client &client,
|
||||
resource::request &request)
|
||||
{
|
||||
const auto access_token("abcdef");
|
||||
const auto home_server("cdc.z");
|
||||
const auto user_id("foo@bar");
|
||||
const auto refresh_token(12345);
|
||||
const auto kind
|
||||
{
|
||||
request.query["kind"]
|
||||
};
|
||||
|
||||
if(kind.empty() || kind == "guest")
|
||||
{
|
||||
char user_id[m::USER_ID_BUFSIZE]; m::id
|
||||
{
|
||||
"randy12345", home_server, user_id
|
||||
};
|
||||
char access_token[m::ACCESS_TOKEN_BUFSIZE];
|
||||
m::access_token_generate(access_token, sizeof(access_token));
|
||||
ircd::resource::tokens.emplace(access_token, &client); //TODO: XXX
|
||||
value<> token_to_user_id{"token", access_token};
|
||||
token_to_user_id = user_id;
|
||||
|
||||
return resource::response
|
||||
{
|
||||
client, http::CREATED, json::obj
|
||||
{
|
||||
{ "access_token", access_token },
|
||||
{ "home_server", home_server },
|
||||
{ "user_id", user_id },
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const auto type
|
||||
{
|
||||
// "Required. The login type that the client is attempting to complete."
|
||||
unquote(request.at("auth.type"))
|
||||
};
|
||||
|
||||
if(type != "m.login.dummy")
|
||||
throw m::error
|
||||
{
|
||||
"M_UNSUPPORTED", "Registration '%s' not supported.", type
|
||||
};
|
||||
|
||||
const auto username
|
||||
{
|
||||
// "The local part of the desired Matrix ID. If omitted, the homeserver MUST "
|
||||
// "generate a Matrix ID local part."
|
||||
unquote(request.get("username"))
|
||||
};
|
||||
|
||||
if(!username.empty() && !m::username_valid(username))
|
||||
throw m::error
|
||||
{
|
||||
"M_INVALID_USERNAME", "The desired user ID is not a valid user name."
|
||||
};
|
||||
|
||||
const auto pass
|
||||
{
|
||||
// "Required. The desired password for the account."
|
||||
request.at("pass")
|
||||
};
|
||||
|
||||
const auto bind_email
|
||||
{
|
||||
// "If true, the server binds the email used for authentication to the "
|
||||
// "Matrix ID with the ID Server."
|
||||
request.get<bool>("bind_email", false)
|
||||
};
|
||||
|
||||
// Generate fully qualified user id and randomize username if missing
|
||||
char user_id[m::USER_ID_BUFSIZE]; m::id
|
||||
{
|
||||
username, home_server, user_id
|
||||
};
|
||||
|
||||
// Atomic commitment to registration
|
||||
value<time_t> registered{"registered", user_id};
|
||||
{
|
||||
time_t expected(0); // unregistered == empty == 0
|
||||
if(!registered.compare_exchange(expected, time(nullptr)))
|
||||
throw m::error
|
||||
{
|
||||
http::CONFLICT, "M_USER_IN_USE", "The desired user ID is already taken."
|
||||
};
|
||||
}
|
||||
|
||||
// "An access token for the account. This access token can then be used to "
|
||||
// "authorize other requests. The access token may expire at some point, and if "
|
||||
// "so, it SHOULD come with a refresh_token. There is no specific error message to "
|
||||
// "indicate that a request has failed because an access token has expired; "
|
||||
// "instead, if a client has reason to believe its access token is valid, and "
|
||||
// "it receives an auth error, they should attempt to refresh for a new token "
|
||||
// "on failure, and retry the request with the new token."
|
||||
value<> access_token_text{"access_token.text", user_id};
|
||||
|
||||
// Prepare to store password
|
||||
value<> password_text("password.text", user_id);
|
||||
|
||||
// Generate access token
|
||||
char access_token[m::ACCESS_TOKEN_BUFSIZE];
|
||||
m::access_token_generate(access_token, sizeof(access_token));
|
||||
ircd::resource::tokens.emplace(access_token, &client); //TODO: XXX
|
||||
|
||||
// Batch transaction to database
|
||||
db::write
|
||||
({
|
||||
{ db::SET, password_text, pass },
|
||||
{ db::SET, access_token_text, access_token },
|
||||
});
|
||||
|
||||
// Send response to user
|
||||
return resource::response
|
||||
{
|
||||
client,
|
||||
client, http::CREATED, json::obj
|
||||
{
|
||||
{ "access_token", access_token },
|
||||
{ "home_server", home_server },
|
||||
{ "user_id", user_id },
|
||||
{ "refresh_token", refresh_token },
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
resource register_resource
|
||||
{
|
||||
"/_matrix/client/r0/register",
|
||||
"_matrix/client/r0/register",
|
||||
"Register for an account on this homeserver. (3.3.1)"
|
||||
};
|
||||
|
||||
|
|
173
modules/client/room.cc
Normal file
173
modules/client/room.cc
Normal file
|
@ -0,0 +1,173 @@
|
|||
/*
|
||||
* 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"
|
||||
};
|
30
modules/client/room.h
Normal file
30
modules/client/room.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> room_database
|
||||
{
|
||||
"client_room", "room_database"
|
||||
};
|
||||
|
||||
extern ircd::database *const room
|
||||
{
|
||||
room_database.get()
|
||||
};
|
97
modules/client/sync.cc
Normal file
97
modules/client/sync.cc
Normal file
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "account.h"
|
||||
|
||||
using namespace ircd;
|
||||
|
||||
using object = db::object<account>;
|
||||
template<class T = string_view> using value = db::value<T, account>;
|
||||
|
||||
resource sync_resource
|
||||
{
|
||||
"_matrix/client/r0/sync",
|
||||
"Synchronise the client's state with the latest state on the server. "
|
||||
"Clients use this API when they first log in to get an initial snapshot of "
|
||||
"the state on the server, and then continue to call this API to get "
|
||||
"incremental deltas to the state, and to receive new messages. (6.2)"
|
||||
};
|
||||
|
||||
resource::response
|
||||
sync(client &client, const resource::request &request)
|
||||
{
|
||||
const auto filter
|
||||
{
|
||||
// 6.2.1 The ID of a filter created using the filter API or a filter JSON object
|
||||
// encoded as a string. The server will detect whether it is an ID or a JSON object
|
||||
// by whether the first character is a "{" open brace. Passing the JSON inline is best
|
||||
// suited to one off requests. Creating a filter using the filter API is recommended
|
||||
// for clients that reuse the same filter multiple times, for example in long poll requests.
|
||||
request["filter"]
|
||||
};
|
||||
|
||||
const auto since
|
||||
{
|
||||
// 6.2.1 A point in time to continue a sync from.
|
||||
request["since"]
|
||||
};
|
||||
|
||||
const auto full_state
|
||||
{
|
||||
// 6.2.1 Controls whether to include the full state for all rooms the user is a member of.
|
||||
// If this is set to true, then all state events will be returned, even if since is non-empty.
|
||||
// The timeline will still be limited by the since parameter. In this case, the timeout
|
||||
// parameter will be ignored and the query will return immediately, possibly with an
|
||||
// empty timeline. If false, and since is non-empty, only state which has changed since
|
||||
// the point indicated by since will be returned. By default, this is false.
|
||||
request.get<bool>("full_state", false)
|
||||
};
|
||||
|
||||
const auto set_presence
|
||||
{
|
||||
// 6.2.1 Controls whether the client is automatically marked as online by polling this API.
|
||||
// If this parameter is omitted then the client is automatically marked as online when it
|
||||
// uses this API. Otherwise if the parameter is set to "offline" then the client is not
|
||||
// marked as being online when it uses this API. One of: ["offline"]
|
||||
request.get("set_presence", "offline")
|
||||
};
|
||||
|
||||
const auto timeout
|
||||
{
|
||||
// 6.2.1 The maximum time to poll in milliseconds before returning this request.
|
||||
request.get<time_t>("timeout", -1)
|
||||
};
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
resource::method get_sync
|
||||
{
|
||||
sync_resource, "GET", sync,
|
||||
{
|
||||
get_sync.REQUIRES_AUTH
|
||||
}
|
||||
};
|
||||
|
||||
mapi::header IRCD_MODULE
|
||||
{
|
||||
"registers the resource 'client/sync' to handle requests."
|
||||
};
|
147
modules/client/user.cc
Normal file
147
modules/client/user.cc
Normal file
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "account.h"
|
||||
|
||||
using namespace ircd;
|
||||
|
||||
resource user_resource
|
||||
{
|
||||
"_matrix/client/r0/user",
|
||||
"User resource",
|
||||
{
|
||||
resource::DIRECTORY
|
||||
}
|
||||
};
|
||||
|
||||
namespace ircd
|
||||
{
|
||||
static string_view extract_user_id(const auto &path, const auto &suffix);
|
||||
}
|
||||
|
||||
ircd::string_view
|
||||
ircd::extract_user_id(const auto &path,
|
||||
const auto &suffix)
|
||||
{
|
||||
// Extract the user_id from _matrix/client/r0/user/$user/filter
|
||||
return lstrip(between(path, user_resource.path, suffix), '/');
|
||||
}
|
||||
|
||||
resource::response
|
||||
get_filter(client &client, const resource::request &request)
|
||||
try
|
||||
{
|
||||
const auto user_id
|
||||
{
|
||||
extract_user_id(request.head.path, "/filter")
|
||||
};
|
||||
|
||||
return resource::response
|
||||
{
|
||||
client, json::obj
|
||||
{
|
||||
{ }
|
||||
}
|
||||
};
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
resource::method get
|
||||
{
|
||||
user_resource, "GET", get_filter
|
||||
};
|
||||
|
||||
// (5.2) Uploads a new filter definition to the homeserver. Returns a filter ID that
|
||||
// may be used in future requests to restrict which events are returned to the client.
|
||||
resource::response
|
||||
post_filter(client &client, const resource::request &request)
|
||||
try
|
||||
{
|
||||
const auto user_id
|
||||
{
|
||||
// (5.2) Required. The id of the user uploading the filter. The access
|
||||
// token must be authorized to make requests for this user id.
|
||||
extract_user_id(request.head.path, "/filter")
|
||||
};
|
||||
|
||||
const auto event_fields
|
||||
{
|
||||
// (5.2) List of event fields to include. If this list is absent then all fields are
|
||||
// included. The entries may include '.' charaters to indicate sub-fields. So
|
||||
// ['content.body'] will include the 'body' field of the 'content' object. A literal '.'
|
||||
// character in a field name may be escaped using a '\'. A server may include more
|
||||
// fields than were requested.
|
||||
request["event_fields"]
|
||||
};
|
||||
|
||||
const auto event_format
|
||||
{
|
||||
// (5.2) The format to use for events. 'client' will return the events in a format suitable
|
||||
// for clients. 'federation' will return the raw event as receieved over federation.
|
||||
// The default is 'client'. One of: ["client", "federation"]
|
||||
request["event_format"]
|
||||
};
|
||||
|
||||
const auto account_data
|
||||
{
|
||||
// (5.2) The user account data that isn't associated with rooms to include.
|
||||
request["account_data"]
|
||||
};
|
||||
|
||||
const auto room
|
||||
{
|
||||
// (5.2) Filters to be applied to room data.
|
||||
request["room"]
|
||||
};
|
||||
|
||||
const auto presence
|
||||
{
|
||||
// (5.2) The presence updates to include.
|
||||
request["presence"]
|
||||
};
|
||||
|
||||
std::cout << "do filter: " << request.content << std::endl;
|
||||
|
||||
return resource::response
|
||||
{
|
||||
client, http::CREATED, json::obj
|
||||
{
|
||||
{ "filter_id", "abc321" }
|
||||
}
|
||||
};
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
resource::method post
|
||||
{
|
||||
user_resource, "POST", post_filter
|
||||
};
|
||||
|
||||
mapi::header IRCD_MODULE
|
||||
{
|
||||
"registers the resource 'client/user' to handle requests"
|
||||
};
|
|
@ -23,7 +23,7 @@ using namespace ircd;
|
|||
|
||||
resource versions_resource
|
||||
{
|
||||
"/_matrix/client/versions",
|
||||
"_matrix/client/versions",
|
||||
"Gets the versions of the specification supported by the server (2.1)"
|
||||
};
|
||||
|
||||
|
@ -35,7 +35,7 @@ resource::method getter
|
|||
{
|
||||
static const json::doc object
|
||||
{
|
||||
R"({"versions":["r0.0.1"]})"
|
||||
R"({"versions":["r2.0.0"]})"
|
||||
};
|
||||
|
||||
return resource::response { client, object };
|
||||
|
|
54
modules/client/voip/turnserver.cc
Normal file
54
modules/client/voip/turnserver.cc
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
mapi::header IRCD_MODULE
|
||||
{
|
||||
"registers the resource 'client/voip/turnserver' to handle requests."
|
||||
};
|
||||
|
||||
resource turnserver_resource
|
||||
{
|
||||
"_matrix/client/r0/voip/turnServer",
|
||||
"This API provides credentials for the client to use when initiating calls."
|
||||
"(11.3.3)"
|
||||
};
|
||||
|
||||
resource::response
|
||||
get_turnserver(client &client, const resource::request &request)
|
||||
{
|
||||
return resource::response
|
||||
{
|
||||
client, json::obj
|
||||
{
|
||||
{ },
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
resource::method turnserver_get
|
||||
{
|
||||
turnserver_resource, "GET", get_turnserver,
|
||||
{
|
||||
//get_turnserver.REQUIRES_AUTH
|
||||
}
|
||||
};
|
32
modules/ircd.js
Normal file
32
modules/ircd.js
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var ircd =
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
ircd.opts =
|
||||
{
|
||||
|
||||
};
|
70
modules/matrix.cc
Normal file
70
modules/matrix.cc
Normal file
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright (C) 2016 Charybdis Development Team
|
||||
* Copyright (C) 2016 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.
|
||||
*/
|
||||
|
||||
#include <ircd/listen.h>
|
||||
|
||||
using namespace ircd;
|
||||
|
||||
mapi::header IRCD_MODULE
|
||||
{
|
||||
"Chat Matrix Protocol"
|
||||
};
|
||||
|
||||
std::map<std::string, module> modules;
|
||||
|
||||
//TODO: XXX very temporary stuff around here
|
||||
// The path root (serves static assets for web etc); this pointer
|
||||
// exists for now to easily find and reload that specifically.
|
||||
module *root_module;
|
||||
const auto _init_([]
|
||||
{
|
||||
// These modules host databases and have to be loaded first.
|
||||
modules.emplace("client_account.so"s, "client_account.so"s);
|
||||
modules.emplace("client_room.so"s, "client_room.so"s);
|
||||
|
||||
for(const auto &name : mods::available())
|
||||
if(name != "matrix.so")
|
||||
modules.emplace(name, name);
|
||||
|
||||
root_module = &modules.at("root.so"s);
|
||||
return true;
|
||||
}());
|
||||
|
||||
listener matrices
|
||||
{
|
||||
std::string { json::obj
|
||||
{
|
||||
{ "name", "Chat Matrix" },
|
||||
{ "host", "0.0.0.0" },
|
||||
{
|
||||
"ssl_certificate_chain_file", "/home/jason/.synapse/zemos.net.crt"
|
||||
},
|
||||
{
|
||||
"ssl_tmp_dh_file", "/home/jason/.synapse/cdc.z.tls.dh"
|
||||
},
|
||||
{
|
||||
"ssl_private_key_file_pem", "/home/jason/.synapse/cdc.z.tls.key"
|
||||
},
|
||||
{
|
||||
"port", 6667
|
||||
}
|
||||
}}
|
||||
};
|
95
modules/root.cc
Normal file
95
modules/root.cc
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright (C) 2016 Charybdis Development Team
|
||||
* Copyright (C) 2016 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.
|
||||
*/
|
||||
|
||||
#include <iterator>
|
||||
|
||||
using namespace ircd;
|
||||
|
||||
mapi::header IRCD_MODULE
|
||||
{
|
||||
"Chat Matrix Protocol"
|
||||
};
|
||||
|
||||
IRCD_INIT_PRIORITY(STD_CONTAINER)
|
||||
std::map<std::string, std::string, iless> files
|
||||
{
|
||||
};
|
||||
|
||||
__attribute__((constructor))
|
||||
void
|
||||
init_0()
|
||||
{
|
||||
for(const auto &file : fs::ls("/home/jason/charybdis/charybdis/modules/static"))
|
||||
{
|
||||
const auto name(token_last(file, "/"));
|
||||
files.emplace(std::string(name), file);
|
||||
}
|
||||
}
|
||||
|
||||
resource::response
|
||||
get_root(client &client, const resource::request &request)
|
||||
{
|
||||
auto it(files.find(request.head.path));
|
||||
if(it == end(files))
|
||||
throw http::error{http::NOT_FOUND};
|
||||
|
||||
const auto &filename(it->second);
|
||||
std::ifstream file(filename);
|
||||
std::noskipws(file);
|
||||
const std::string content
|
||||
{
|
||||
std::istream_iterator<char>{file}, std::istream_iterator<char>{}
|
||||
};
|
||||
|
||||
string_view content_type; switch(hash(rsplit(filename, '.').second))
|
||||
{
|
||||
case hash("css"): content_type = "text/css; charset=utf-8"; break;
|
||||
case hash("js"): content_type = "application/javascript; charset=utf-8"; break;
|
||||
case hash("html"): content_type = "text/html; charset=utf-8"; break;
|
||||
case hash("ico"): content_type = "image/x-icon"; break;
|
||||
case hash("svg"): content_type = "image/svg+xml"; break;
|
||||
case hash("png"): content_type = "image/png"; break;
|
||||
case hash("woff2"): content_type = "application/font-woff2"; break;
|
||||
case hash("woff"): content_type = "application/font-woff"; break;
|
||||
case hash("eot"): content_type = "application/vnd.ms-fontobject"; break;
|
||||
case hash("otf"):
|
||||
case hash("ttf"): content_type = "application/font-sfnt"; break;
|
||||
default: content_type = "text/plain; charset=utf-8"; break;
|
||||
}
|
||||
|
||||
return resource::response
|
||||
{
|
||||
client, string_view{content}, content_type
|
||||
};
|
||||
}
|
||||
|
||||
resource root_resource
|
||||
{
|
||||
"", "Root resource",
|
||||
{
|
||||
root_resource.DIRECTORY
|
||||
}
|
||||
};
|
||||
|
||||
resource::method root_get
|
||||
{
|
||||
root_resource, "GET", get_root
|
||||
};
|
Loading…
Reference in a new issue