mirror of
https://github.com/matrix-construct/construct
synced 2024-11-29 02:02:38 +01:00
ircd:Ⓜ️ Deduplicate user related in m::user. Update various resource related.
This commit is contained in:
parent
ca1f5bbbe5
commit
d4508e157f
13 changed files with 365 additions and 206 deletions
|
@ -564,7 +564,7 @@ try
|
|||
moi->quote(q);
|
||||
break;
|
||||
}
|
||||
|
||||
*/
|
||||
case hash("password"):
|
||||
{
|
||||
if(!moi)
|
||||
|
@ -575,20 +575,66 @@ try
|
|||
|
||||
const auto args(tokens_after(line, " ", 0));
|
||||
const params token{args, " ", {"new_password"}};
|
||||
m::request::password password
|
||||
{{
|
||||
{ "new_password", token.at(0) },
|
||||
{ "auth",
|
||||
{
|
||||
{ "session", "abcdef" },
|
||||
{ "type", "m.login.token" }
|
||||
}}
|
||||
}};
|
||||
static char query[512]; const auto query_len
|
||||
{
|
||||
fmt::snprintf(query, sizeof(query), "%s=%s",
|
||||
"access_token",
|
||||
moi->access_token)
|
||||
};
|
||||
|
||||
moi->password(password);
|
||||
m::request request
|
||||
{
|
||||
"POST", "_matrix/client/r0/account/password", query, json::members
|
||||
{
|
||||
{ "new_password", token.at(0) },
|
||||
{ "auth", json::members
|
||||
{
|
||||
{ "type", "m.login.password" }
|
||||
}},
|
||||
}
|
||||
};
|
||||
|
||||
static char buf[4096];
|
||||
ircd::parse::buffer pb{buf};
|
||||
const json::object response{(*moi)(pb, request)};
|
||||
std::cout << string_view{response} << std::endl;
|
||||
break;
|
||||
}
|
||||
*/
|
||||
|
||||
case hash("deactivate"):
|
||||
{
|
||||
if(!moi)
|
||||
{
|
||||
std::cerr << "No current session" << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
const auto args(tokens_after(line, " ", 0));
|
||||
static char query[512]; const auto query_len
|
||||
{
|
||||
fmt::snprintf(query, sizeof(query), "%s=%s",
|
||||
"access_token",
|
||||
moi->access_token)
|
||||
};
|
||||
|
||||
m::request request
|
||||
{
|
||||
"POST", "_matrix/client/r0/account/deactivate", query, json::members
|
||||
{
|
||||
{ "auth", json::members
|
||||
{
|
||||
{ "type", "m.login.password" }
|
||||
}},
|
||||
}
|
||||
};
|
||||
|
||||
static char buf[4096];
|
||||
ircd::parse::buffer pb{buf};
|
||||
const json::object response{(*moi)(pb, request)};
|
||||
std::cout << string_view{response} << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
case hash("setfilter"):
|
||||
{
|
||||
if(!moi)
|
||||
|
|
|
@ -109,6 +109,8 @@ struct ircd::m::filter
|
|||
json::property<name::presence, event_filter>
|
||||
>
|
||||
{
|
||||
static room filters;
|
||||
|
||||
using super_type::tuple;
|
||||
using super_type::operator=;
|
||||
};
|
||||
|
|
|
@ -28,10 +28,10 @@
|
|||
namespace ircd::m
|
||||
{
|
||||
struct user;
|
||||
}
|
||||
|
||||
namespace ircd::m::users
|
||||
{
|
||||
extern user me;
|
||||
extern room my_room;
|
||||
extern room filters;
|
||||
}
|
||||
|
||||
struct ircd::m::user
|
||||
|
@ -40,10 +40,16 @@ struct ircd::m::user
|
|||
|
||||
id user_id;
|
||||
|
||||
user(const id &user_id);
|
||||
};
|
||||
static room accounts;
|
||||
|
||||
inline
|
||||
ircd::m::user::user(const id &user_id)
|
||||
:user_id{user_id}
|
||||
{}
|
||||
bool is_active() const;
|
||||
bool is_password(const string_view &password) const;
|
||||
|
||||
void password(const string_view &password);
|
||||
void activate(const json::members &contents = {});
|
||||
void deactivate(const json::members &contents = {});
|
||||
|
||||
user(const id &user_id)
|
||||
:user_id{user_id}
|
||||
{}
|
||||
};
|
||||
|
|
|
@ -77,6 +77,7 @@ struct ircd::resource::request
|
|||
const http::request::head &head;
|
||||
http::request::content &content;
|
||||
http::query::string query;
|
||||
m::user::id::buf user_id;
|
||||
|
||||
request(const http::request::head &head, http::request::content &content, http::query::string query);
|
||||
};
|
||||
|
|
|
@ -227,13 +227,14 @@ namespace ircd
|
|||
#include "fmt.h"
|
||||
#include "fs.h"
|
||||
#include "ctx.h"
|
||||
#include "resource.h"
|
||||
#include "logger.h"
|
||||
#include "db.h"
|
||||
#include "js.h"
|
||||
#include "client.h"
|
||||
#include "mods.h"
|
||||
#include "listen.h"
|
||||
#include "m.h"
|
||||
#include "resource.h"
|
||||
|
||||
template<class T>
|
||||
std::string
|
||||
|
|
|
@ -33,8 +33,6 @@
|
|||
#include <rocksdb/env.h>
|
||||
#include <rocksdb/slice_transform.h>
|
||||
|
||||
#include <ircd/m.h>
|
||||
|
||||
namespace ircd::db
|
||||
{
|
||||
const auto BLOCKING = rocksdb::ReadTier::kReadAllTier;
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
*/
|
||||
|
||||
#include <ircd/asio.h>
|
||||
#include <ircd/m.h>
|
||||
|
||||
namespace ircd
|
||||
{
|
||||
|
|
217
ircd/matrix.cc
217
ircd/matrix.cc
|
@ -19,8 +19,6 @@
|
|||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <ircd/m.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// m/session.h
|
||||
|
@ -87,6 +85,24 @@ namespace ircd::m
|
|||
void bootstrap();
|
||||
}
|
||||
|
||||
ircd::m::user
|
||||
ircd::m::me
|
||||
{
|
||||
"@ircd:cdc.z"
|
||||
};
|
||||
|
||||
ircd::m::room
|
||||
ircd::m::my_room
|
||||
{
|
||||
ircd::m::room::id{"!ircd:cdc.z"}
|
||||
};
|
||||
|
||||
ircd::m::room
|
||||
ircd::m::filter::filters
|
||||
{
|
||||
ircd::m::room::id{"!filters:cdc.z"}
|
||||
};
|
||||
|
||||
ircd::m::init::init()
|
||||
try
|
||||
{
|
||||
|
@ -139,12 +155,8 @@ ircd::m::join_ircd_room()
|
|||
try
|
||||
{
|
||||
// ircd.start event
|
||||
const m::id::room::buf room_id{"ircd", "cdc.z"};
|
||||
const m::id::user::buf user_id{"ircd", "cdc.z"};
|
||||
m::room ircd_room{room_id};
|
||||
|
||||
json::iov content;
|
||||
ircd_room.join(user_id, content);
|
||||
my_room.join(me.user_id, content);
|
||||
}
|
||||
catch(const m::ALREADY_MEMBER &e)
|
||||
{
|
||||
|
@ -155,12 +167,8 @@ void
|
|||
ircd::m::leave_ircd_room()
|
||||
{
|
||||
// ircd.start event
|
||||
const m::id::room::buf room_id{"ircd", "cdc.z"};
|
||||
const m::id::user::buf user_id{"ircd", "cdc.z"};
|
||||
m::room ircd_room{room_id};
|
||||
|
||||
json::iov content;
|
||||
ircd_room.leave(user_id, content);
|
||||
my_room.leave(me.user_id, content);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -175,46 +183,38 @@ ircd::m::bootstrap()
|
|||
"database is empty. I will be bootstrapping it with initial events now..."
|
||||
);
|
||||
|
||||
const m::id::user::buf user_id{"ircd", "cdc.z"};
|
||||
const m::id::room::buf ircd_room_id{"ircd", "cdc.z"};
|
||||
m::room ircd_room{ircd_room_id};
|
||||
ircd_room.send(
|
||||
my_room.send(
|
||||
{
|
||||
{ "type", "m.room.create" },
|
||||
{ "sender", user_id },
|
||||
{ "sender", me.user_id },
|
||||
{ "state_key", "" },
|
||||
{ "content", json::members
|
||||
{
|
||||
{ "creator", user_id }
|
||||
{ "creator", me.user_id }
|
||||
}}
|
||||
});
|
||||
|
||||
const m::id::room::buf accounts_room_id{"accounts", "cdc.z"};
|
||||
m::room accounts_room{accounts_room_id};
|
||||
accounts_room.send(
|
||||
user::accounts.send(
|
||||
{
|
||||
{ "type", "m.room.create" },
|
||||
{ "sender", user_id },
|
||||
{ "sender", me.user_id },
|
||||
{ "state_key", "" },
|
||||
{ "content", json::members
|
||||
{
|
||||
{ "creator", user_id }
|
||||
{ "creator", me.user_id }
|
||||
}}
|
||||
});
|
||||
|
||||
json::iov content;
|
||||
accounts_room.join(user_id, content);
|
||||
|
||||
const m::id::room::buf filters_room_id{"filters", "cdc.z"};
|
||||
m::room filters_room{filters_room_id};
|
||||
filters_room.send(
|
||||
user::accounts.join(me.user_id, content);
|
||||
filter::filters.send(
|
||||
{
|
||||
{ "type", "m.room.create" },
|
||||
{ "sender", user_id },
|
||||
{ "sender", me.user_id },
|
||||
{ "state_key", "" },
|
||||
{ "content", json::members
|
||||
{
|
||||
{ "creator", user_id }
|
||||
{ "creator", me.user_id }
|
||||
}}
|
||||
});
|
||||
}
|
||||
|
@ -638,6 +638,163 @@ const
|
|||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// m/user.h
|
||||
//
|
||||
|
||||
ircd::m::room
|
||||
ircd::m::user::accounts
|
||||
{
|
||||
ircd::m::room::id{"!accounts:cdc.z"}
|
||||
};
|
||||
|
||||
/// Register the user by joining them to the accounts room.
|
||||
///
|
||||
/// The content of the join event may store keys including the registration
|
||||
/// options. Once this call completes the join was successful and the user is
|
||||
/// registered, otherwise throws.
|
||||
void
|
||||
ircd::m::user::activate(const json::members &contents)
|
||||
try
|
||||
{
|
||||
json::iov content;
|
||||
json::iov::push members[contents.size()];
|
||||
|
||||
size_t i(0);
|
||||
for(const auto &member : contents)
|
||||
new (members + i++) json::iov::push(content, member);
|
||||
|
||||
accounts.join(user_id, content);
|
||||
}
|
||||
catch(const m::ALREADY_MEMBER &e)
|
||||
{
|
||||
throw m::error
|
||||
{
|
||||
http::CONFLICT, "M_USER_IN_USE", "The desired user ID is already in use."
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
ircd::m::user::deactivate(const json::members &contents)
|
||||
{
|
||||
json::iov content;
|
||||
json::iov::push members[contents.size()];
|
||||
|
||||
size_t i(0);
|
||||
for(const auto &member : contents)
|
||||
new (members + i++) json::iov::push(content, member);
|
||||
|
||||
accounts.leave(user_id, content);
|
||||
}
|
||||
|
||||
void
|
||||
ircd::m::user::password(const string_view &password)
|
||||
try
|
||||
{
|
||||
json::iov event;
|
||||
json::iov::push members[]
|
||||
{
|
||||
{ event, json::member { "type", "ircd.password" }},
|
||||
{ event, json::member { "state_key", user_id }},
|
||||
{ event, json::member { "sender", user_id }},
|
||||
{ event, json::member { "content", json::members
|
||||
{
|
||||
{ "plaintext", password }
|
||||
}}},
|
||||
};
|
||||
|
||||
accounts.send(event);
|
||||
}
|
||||
catch(const m::ALREADY_MEMBER &e)
|
||||
{
|
||||
throw m::error
|
||||
{
|
||||
http::CONFLICT, "M_USER_IN_USE", "The desired user ID is already in use."
|
||||
};
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::user::is_password(const string_view &supplied_password)
|
||||
const
|
||||
{
|
||||
const m::event::where::equal member_event
|
||||
{
|
||||
{ "type", "ircd.password" },
|
||||
{ "state_key", user_id }
|
||||
};
|
||||
|
||||
bool ret{false};
|
||||
const m::event::where::test correct_password{[&ret, &supplied_password]
|
||||
(const auto &event)
|
||||
{
|
||||
const json::object &content
|
||||
{
|
||||
json::at<m::name::content>(event)
|
||||
};
|
||||
|
||||
const auto &correct_password
|
||||
{
|
||||
unquote(content.at("plaintext"))
|
||||
};
|
||||
|
||||
ret = supplied_password == correct_password;
|
||||
return true;
|
||||
}};
|
||||
|
||||
const auto query
|
||||
{
|
||||
member_event && correct_password
|
||||
};
|
||||
|
||||
// The query to the database is made here. Know that this ircd::ctx
|
||||
// may suspend and global state may have changed after this call.
|
||||
const room::events events
|
||||
{
|
||||
accounts
|
||||
};
|
||||
|
||||
events.query(member_event && correct_password);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::user::is_active()
|
||||
const
|
||||
{
|
||||
const m::event::where::equal member_event
|
||||
{
|
||||
{ "type", "m.room.member" },
|
||||
{ "state_key", user_id }
|
||||
};
|
||||
|
||||
bool ret{false};
|
||||
const m::event::where::test is_joined{[&ret]
|
||||
(const auto &event)
|
||||
{
|
||||
const json::object &content
|
||||
{
|
||||
json::val<m::name::content>(event)
|
||||
};
|
||||
|
||||
const auto &membership
|
||||
{
|
||||
unquote(content["membership"])
|
||||
};
|
||||
|
||||
ret = membership == "join";
|
||||
return true;
|
||||
}};
|
||||
|
||||
const room::events events
|
||||
{
|
||||
accounts
|
||||
};
|
||||
|
||||
events.query(member_event && is_joined);
|
||||
return ret;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// m/event.h
|
||||
|
|
|
@ -19,8 +19,6 @@
|
|||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <ircd/m.h>
|
||||
|
||||
namespace ircd {
|
||||
|
||||
IRCD_INIT_PRIORITY(STD_CONTAINER)
|
||||
|
@ -108,7 +106,7 @@ noexcept
|
|||
|
||||
namespace ircd {
|
||||
|
||||
const m::room accounts
|
||||
const m::room::events accounts
|
||||
{
|
||||
m::id::room{"!accounts:cdc.z"}
|
||||
};
|
||||
|
@ -119,7 +117,7 @@ authenticate(client &client,
|
|||
resource::request &request)
|
||||
try
|
||||
{
|
||||
const auto &access_token
|
||||
const string_view &access_token
|
||||
{
|
||||
request.query.at("access_token")
|
||||
};
|
||||
|
@ -131,7 +129,17 @@ try
|
|||
{ "state_key", access_token }
|
||||
};
|
||||
|
||||
if(!m::room::events{accounts}.any(query))
|
||||
const bool result
|
||||
{
|
||||
accounts.query(query, [&request, &access_token](const m::event &event)
|
||||
{
|
||||
assert(at<m::name::state_key>(event) == access_token);
|
||||
request.user_id = at<m::name::sender>(event);
|
||||
return true;
|
||||
})
|
||||
};
|
||||
|
||||
if(!result)
|
||||
throw m::error
|
||||
{
|
||||
// When credentials are required but missing or invalid, the HTTP call will return with
|
||||
|
|
|
@ -48,47 +48,36 @@ resource::response
|
|||
account_password(client &client, const resource::request &request)
|
||||
try
|
||||
{
|
||||
const auto new_password
|
||||
const string_view &new_password
|
||||
{
|
||||
request.at("new_password")
|
||||
unquote(request.at("new_password"))
|
||||
};
|
||||
|
||||
const auto type
|
||||
const string_view &type
|
||||
{
|
||||
unquote(request.at("auth.type"))
|
||||
unquote(request.at({"auth", "type"}))
|
||||
};
|
||||
|
||||
const auto session
|
||||
{
|
||||
request["auth.session"]
|
||||
};
|
||||
|
||||
if(!type.empty() && type != "m.login.token")
|
||||
{
|
||||
if(type != "m.login.password")
|
||||
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
|
||||
const string_view &session
|
||||
{
|
||||
json::index
|
||||
{{
|
||||
"password",
|
||||
{
|
||||
{ "plaintext", new_password }
|
||||
}
|
||||
}}
|
||||
});
|
||||
*/
|
||||
request[{"auth", "session"}]
|
||||
};
|
||||
|
||||
m::user user
|
||||
{
|
||||
request.user_id
|
||||
};
|
||||
|
||||
user.password(new_password);
|
||||
return resource::response
|
||||
{
|
||||
client
|
||||
client, http::OK
|
||||
};
|
||||
}
|
||||
catch(const db::not_found &e)
|
||||
|
@ -99,9 +88,49 @@ catch(const db::not_found &e)
|
|||
};
|
||||
}
|
||||
|
||||
resource::method post
|
||||
resource::method post_password
|
||||
{
|
||||
account_resource.password, "POST", account_password
|
||||
account_resource.password, "POST", account_password,
|
||||
{
|
||||
post_password.REQUIRES_AUTH
|
||||
}
|
||||
};
|
||||
|
||||
resource::response
|
||||
account_deactivate(client &client, const resource::request &request)
|
||||
{
|
||||
const string_view &type
|
||||
{
|
||||
request.at({"auth", "type"})
|
||||
};
|
||||
|
||||
const string_view &session
|
||||
{
|
||||
request[{"auth", "session"}]
|
||||
};
|
||||
|
||||
m::user user
|
||||
{
|
||||
request.user_id
|
||||
};
|
||||
|
||||
user.deactivate();
|
||||
|
||||
return resource::response
|
||||
{
|
||||
client, json::members
|
||||
{
|
||||
{ "goodbye", "Thanks for visiting. Come back soon!" }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
resource::method post_deactivate
|
||||
{
|
||||
account_resource.deactivate, "POST", account_deactivate,
|
||||
{
|
||||
post_deactivate.REQUIRES_AUTH
|
||||
}
|
||||
};
|
||||
|
||||
mapi::header IRCD_MODULE
|
||||
|
|
|
@ -56,24 +56,6 @@ struct body
|
|||
using super_type::tuple;
|
||||
};
|
||||
|
||||
// Generate !accounts:host which is the MXID of the room where the members
|
||||
// are the actual account registrations for this homeserver.
|
||||
const m::id::room::buf accounts_room_id
|
||||
{
|
||||
"accounts", home_server
|
||||
};
|
||||
|
||||
// Handle to the accounts room
|
||||
m::room accounts_room
|
||||
{
|
||||
accounts_room_id
|
||||
};
|
||||
|
||||
const m::room::events accounts_room_events
|
||||
{
|
||||
accounts_room
|
||||
};
|
||||
|
||||
resource::response
|
||||
post_login_password(client &client,
|
||||
const resource::request::object<body> &request)
|
||||
|
@ -92,56 +74,21 @@ post_login_password(client &client,
|
|||
|
||||
const auto &supplied_password
|
||||
{
|
||||
at<name::password>(request)
|
||||
unquote(at<name::password>(request))
|
||||
};
|
||||
|
||||
// Sets up the query to find the user_id in the accounts room
|
||||
const m::event::where::equal member_event
|
||||
m::user user
|
||||
{
|
||||
{ "type", "m.room.member" },
|
||||
{ "state_key", user_id }
|
||||
user_id
|
||||
};
|
||||
|
||||
// Once the query finds the result this closure views the event in the
|
||||
// database and returns true if the login is authentic.
|
||||
const m::event::where::test correct_password{[&supplied_password]
|
||||
(const auto &event)
|
||||
{
|
||||
const json::object &content
|
||||
if(!user.is_password(supplied_password))
|
||||
throw m::error
|
||||
{
|
||||
json::val<m::name::content>(event)
|
||||
http::FORBIDDEN, "M_FORBIDDEN", "Access denied."
|
||||
};
|
||||
|
||||
const auto &membership
|
||||
{
|
||||
unquote(content.at("membership"))
|
||||
};
|
||||
|
||||
if(membership != "join")
|
||||
return false;
|
||||
|
||||
const auto &correct_password
|
||||
{
|
||||
content.get("password")
|
||||
};
|
||||
|
||||
if(!correct_password)
|
||||
return false;
|
||||
|
||||
if(supplied_password != correct_password)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}};
|
||||
|
||||
const auto query
|
||||
{
|
||||
member_event && correct_password
|
||||
};
|
||||
|
||||
// The query to the database is made here. Know that this ircd::ctx
|
||||
// may suspend and global state may have changed after this call.
|
||||
if(!accounts_room_events.query(query))
|
||||
if(!user.is_active())
|
||||
throw m::error
|
||||
{
|
||||
http::FORBIDDEN, "M_FORBIDDEN", "Access denied."
|
||||
|
@ -159,7 +106,7 @@ post_login_password(client &client,
|
|||
// Log the user in by issuing an event in the accounts room containing
|
||||
// the generated token. When this call completes without throwing the
|
||||
// access_token will be committed and the user will be logged in.
|
||||
accounts_room.send(
|
||||
m::user::accounts.send(
|
||||
{
|
||||
{ "type", "ircd.access_token" },
|
||||
{ "sender", user_id },
|
||||
|
|
|
@ -47,24 +47,8 @@ struct body
|
|||
using super_type::tuple;
|
||||
};
|
||||
|
||||
// Generate !accounts:host which is the MXID of the room where the members
|
||||
// are the account registrations on this homeserver.
|
||||
const m::id::room::buf accounts_room_id
|
||||
{
|
||||
"accounts", home_server
|
||||
};
|
||||
|
||||
// This object is a lightweight handle to the accounts room, which is a
|
||||
// chatroom whose members are the representation of the accounts registered
|
||||
// to this server itself.
|
||||
m::room accounts_room
|
||||
{
|
||||
accounts_room_id
|
||||
};
|
||||
|
||||
static void validate_user_id(const m::id::user &user_id);
|
||||
static void validate_password(const string_view &password);
|
||||
static void join_accounts_room(const m::id::user &user_id, const json::members &contents);
|
||||
|
||||
resource::response
|
||||
handle_post_kind_user(client &client,
|
||||
|
@ -123,17 +107,25 @@ handle_post_kind_user(client &client,
|
|||
// Check if the password is acceptable for this server or throws
|
||||
validate_password(password);
|
||||
|
||||
// Register the user by joining them to the accounts room. The content of
|
||||
// the join event will store keys from the registration options including
|
||||
// the password - do not expose this to clients //TODO: store hashed pass
|
||||
// Once this call completes the join was successful and the user is
|
||||
// registered, otherwise throws.
|
||||
join_accounts_room(user_id,
|
||||
// Represent the user
|
||||
m::user user
|
||||
{
|
||||
user_id
|
||||
};
|
||||
|
||||
// Activate the account. Underneath this will join the user to the room
|
||||
// !accounts:your.domain. If the user_id is already a member then this
|
||||
// throws 409 Conflict; otherwise the user is registered after this call.
|
||||
user.activate(
|
||||
{
|
||||
{ "password", password },
|
||||
{ "bind_email", bind_email },
|
||||
});
|
||||
|
||||
// Set the password for the account. This issues an ircd.password state
|
||||
// event to the accounts room for the user. If this call completes the
|
||||
// user will be able to login with m.login.password
|
||||
user.password(password);
|
||||
|
||||
// Send response to user
|
||||
return resource::response
|
||||
{
|
||||
|
@ -203,28 +195,6 @@ mapi::header IRCD_MODULE
|
|||
"registers the resource 'client/register' to handle requests"
|
||||
};
|
||||
|
||||
void
|
||||
join_accounts_room(const m::id::user &user_id,
|
||||
const json::members &contents)
|
||||
try
|
||||
{
|
||||
json::iov content;
|
||||
json::iov::push members[contents.size()];
|
||||
|
||||
size_t i(0);
|
||||
for(const auto &member : contents)
|
||||
new (members + i++) json::iov::push(content, member);
|
||||
|
||||
accounts_room.join(user_id, content);
|
||||
}
|
||||
catch(const m::ALREADY_MEMBER &e)
|
||||
{
|
||||
throw m::error
|
||||
{
|
||||
http::CONFLICT, "M_USER_IN_USE", "The desired user ID is already in use."
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
validate_user_id(const m::id::user &user_id)
|
||||
{
|
||||
|
|
|
@ -30,16 +30,6 @@ resource user_resource
|
|||
}
|
||||
};
|
||||
|
||||
m::room filters_room
|
||||
{
|
||||
m::room::id{"!filters:cdc.z"}
|
||||
};
|
||||
|
||||
const m::room::events filters_room_events
|
||||
{
|
||||
filters_room
|
||||
};
|
||||
|
||||
resource::response
|
||||
get_filter(client &client, const resource::request &request)
|
||||
try
|
||||
|
@ -77,6 +67,11 @@ try
|
|||
return true;
|
||||
}};
|
||||
|
||||
const m::room::events filters_room_events
|
||||
{
|
||||
m::filter::filters
|
||||
};
|
||||
|
||||
if(!filters_room_events.any(query, result))
|
||||
throw m::NOT_FOUND("No matching filter with that ID");
|
||||
|
||||
|
@ -166,7 +161,7 @@ try
|
|||
{ event, json::member { "content", request.body }}
|
||||
};
|
||||
|
||||
filters_room.send(event);
|
||||
m::filter::filters.send(event);
|
||||
return resource::response
|
||||
{
|
||||
client, http::CREATED,
|
||||
|
|
Loading…
Reference in a new issue