0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-10-31 19:08:59 +01:00
construct/modules/client/room_keys/version.cc

367 lines
6.5 KiB
C++

// The Construct
//
// Copyright (C) The Construct Developers, Authors & Contributors
// Copyright (C) 2016-2020 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.
#include "room_keys.h"
namespace ircd::m
{
static resource::response get_room_keys_version(client &, const resource::request &);
extern resource::method room_keys_version_get;
static resource::response put_room_keys_version(client &, const resource::request &);
extern resource::method room_keys_version_put;
static resource::response delete_room_keys_version(client &, const resource::request &);
extern resource::method room_keys_version_delete;
static resource::response post_room_keys_version(client &, const resource::request &);
extern resource::method room_keys_version_post;
extern resource room_keys_version;
}
decltype(ircd::m::room_keys_version)
ircd::m::room_keys_version
{
"/_matrix/client/unstable/room_keys/version",
{
"(undocumented) Room Keys Version",
resource::DIRECTORY,
}
};
//
// POST
//
decltype(ircd::m::room_keys_version_post)
ircd::m::room_keys_version_post
{
room_keys_version, "POST", post_room_keys_version,
{
room_keys_version_post.REQUIRES_AUTH |
room_keys_version_post.RATE_LIMITED
}
};
ircd::m::resource::response
ircd::m::post_room_keys_version(client &client,
const resource::request &request)
{
const json::string &algorithm
{
request["algorithm"]
};
const json::object &auth_data
{
request["auth_data"]
};
const json::string &public_key
{
auth_data["public_key"]
};
const json::object &signatures
{
auth_data["signatures"]
};
const m::device::id::buf device_id
{
m::user::tokens::device(request.access_token)
};
const m::user::room user_room
{
request.user_id
};
const auto event_id
{
m::send(user_room, request.user_id, "ircd.room_keys.version", json::object
{
request
})
};
const json::value version
{
lex_cast(m::index(event_id)), json::STRING
};
return resource::response
{
client, json::members
{
{ "version", version }
}
};
}
//
// DELETE
//
decltype(ircd::m::room_keys_version_delete)
ircd::m::room_keys_version_delete
{
room_keys_version, "DELETE", delete_room_keys_version,
{
room_keys_version_delete.REQUIRES_AUTH |
room_keys_version_delete.RATE_LIMITED
}
};
ircd::m::resource::response
ircd::m::delete_room_keys_version(client &client,
const resource::request &request)
{
if(request.parv.size() < 1)
throw m::NEED_MORE_PARAMS
{
"version path parameter required",
};
const m::user::room user_room
{
request.user_id
};
const event::idx event_idx
{
lex_cast<event::idx>(request.parv[0])
};
if(m::room_id(event_idx) != user_room.room_id)
throw m::ACCESS_DENIED
{
"Event idx:%lu is not in your room",
event_idx,
};
const auto event_id
{
m::event_id(event_idx)
};
const auto redact_id
{
m::redact(user_room, request.user_id, event_id, "deleted by client")
};
return resource::response
{
client, http::OK
};
}
//
// PUT
//
decltype(ircd::m::room_keys_version_put)
ircd::m::room_keys_version_put
{
room_keys_version, "PUT", put_room_keys_version,
{
room_keys_version_put.REQUIRES_AUTH |
room_keys_version_put.RATE_LIMITED
}
};
ircd::m::resource::response
ircd::m::put_room_keys_version(client &client,
const resource::request &request)
{
if(request.parv.size() < 1)
throw m::NEED_MORE_PARAMS
{
"version path parameter required",
};
const m::user::room user_room
{
request.user_id
};
const event::idx event_idx
{
lex_cast<event::idx>(request.parv[0])
};
if(m::room_id(event_idx) != user_room.room_id)
throw m::ACCESS_DENIED
{
"Event idx:%lu is not in your room",
event_idx,
};
const json::string &algorithm
{
request["algorithm"]
};
const json::object &auth_data
{
request["auth_data"]
};
const auto event_id
{
m::event_id(event_idx)
};
const json::member relates[]
{
{ "event_id", event_id },
{ "rel_type", "m.replace" },
};
const json::strung content
{
json::insert(request, json::members
{
{ "m.relates_to", relates }
})
};
const auto update_id
{
m::send(user_room, request.user_id, "ircd.room_keys.version", json::object
{
content
})
};
return resource::response
{
client, http::OK
};
}
//
// GET
//
decltype(ircd::m::room_keys_version_get)
ircd::m::room_keys_version_get
{
room_keys_version, "GET", get_room_keys_version,
{
room_keys_version_get.REQUIRES_AUTH |
room_keys_version_get.RATE_LIMITED
}
};
ircd::m::resource::response
ircd::m::get_room_keys_version(client &client,
const resource::request &request)
{
const m::user::room user_room
{
request.user_id
};
event::idx event_idx
{
request.parv.size() >= 1?
lex_cast<event::idx>(request.parv[0]):
0UL
};
if(!event_idx)
{
const m::room::type events
{
user_room, "ircd.room_keys.version"
};
events.for_each([&event_idx]
(const auto &, const auto &, const event::idx &_event_idx)
{
if(m::redacted(_event_idx))
return true;
event_idx = _event_idx;
return false; // false to break after this first hit
});
}
if(!event_idx)
throw m::NOT_FOUND
{
"No version found.",
};
if(m::room_id(event_idx) != user_room.room_id)
throw m::ACCESS_DENIED
{
"Event idx:%lu is not in your room",
event_idx,
};
if(m::redacted(event_idx))
throw m::NOT_FOUND
{
"No version found.",
};
const m::replaced latest_idx
{
event_idx, m::replaced::latest
};
const event::idx version_idx
{
latest_idx?
event::idx{latest_idx}:
event_idx
};
const m::room::state state
{
user_room
};
m::get(version_idx, "content", [&client, &event_idx, &state]
(const json::object &content)
{
const auto &[count, etag]
{
count_etag(state, event_idx)
};
const json::value _etag
{
lex_cast(etag), json::STRING
};
const json::value version
{
lex_cast(event_idx), json::STRING
};
resource::response
{
client, json::members
{
{ "algorithm", content["algorithm"] },
{ "auth_data", content["auth_data"] },
{ "count", count },
{ "etag", _etag },
{ "version", version },
}
};
});
return {}; // Responded from closure
}