0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-11-15 22:41:12 +01:00
construct/modules/client/logout.cc

181 lines
3.2 KiB
C++

// Matrix Construct
//
// Copyright (C) Matrix Construct Developers, Authors & Contributors
// Copyright (C) 2016-2018 Jason Volk <jason@zemos.net>
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice is present in all copies. The
// full license for this software is available in the LICENSE file.
using namespace ircd;
static bool
do_logout(const m::user::id &user_id,
const m::event::idx &token_event_idx);
static m::resource::response
post__logout(client &,
const m::resource::request &);
static m::resource::response
post__logout_all(client &,
const m::resource::request &);
mapi::header
IRCD_MODULE
{
"Client 3.3.2 :Logout"
};
m::resource
logout_resource
{
"/_matrix/client/r0/logout",
{
"(3.3.2) Invalidates an existing access token, so that it can no"
" longer be used for authorization."
}
};
m::resource
logout_all_resource
{
"/_matrix/client/r0/logout/all",
{
"(5.4.4) Invalidates all access tokens for a user, so that they can no"
" longer be used for authorization. This includes the access token"
" that made this request."
}
};
m::resource::method
post_method
{
logout_resource, "POST", post__logout,
{
post_method.REQUIRES_AUTH
}
};
m::resource::method
post_all_method
{
logout_all_resource, "POST", post__logout_all,
{
post_all_method.REQUIRES_AUTH
}
};
m::resource::response
post__logout(client &client,
const m::resource::request &request)
{
const auto &access_token
{
request.access_token
};
const m::room::id::buf tokens_room_id
{
"tokens", origin(m::my())
};
const m::room::state tokens
{
tokens_room_id
};
const auto token_event_idx
{
tokens.get("ircd.access_token", access_token)
};
do_logout(request.user_id, token_event_idx);
return m::resource::response
{
client, http::OK
};
}
m::resource::response
post__logout_all(client &client,
const m::resource::request &request)
{
const m::room::id::buf tokens_room_id
{
"tokens", origin(m::my())
};
const m::room::state tokens
{
tokens_room_id
};
long count(0);
tokens.for_each("ircd.access_token", m::event::closure_idx{[&request, &count]
(const m::event::idx &event_idx)
{
bool match(false);
m::get(std::nothrow, event_idx, "sender", [&request, &match]
(const string_view &sender)
{
match = request.user_id == sender;
});
if(match)
{
do_logout(request.user_id, event_idx);
++count;
}
}});
return m::resource::response
{
client, json::members
{
{ "invalidations", count }
}
};
}
bool
do_logout(const m::user::id &user_id,
const m::event::idx &token_event_idx)
try
{
static const string_view reason
{
"logout"
};
const auto token_event_id
{
m::event_id(token_event_idx)
};
const m::room::id::buf tokens_room_id
{
"tokens", origin(m::my())
};
const auto redaction_event_id
{
m::redact(tokens_room_id, user_id, token_event_id, reason)
};
return true;
}
catch(const std::exception &e)
{
log::error
{
m::log, "Error logging out user '%s' token event_idx:%lu :%s",
string_view{user_id},
token_event_idx,
e.what()
};
return false;
}