Fix Matrix.Event.RoomMember
It now complies with the Matrix spec.
This commit is contained in:
parent
26d144c593
commit
f48eaf4c88
@ -24,13 +24,25 @@ public abstract class Matrix.Event.Base : GLib.Object, GLib.Initable {
|
||||
private bool _inited = false;
|
||||
private Json.Node? _json;
|
||||
|
||||
protected string? _event_type = null;
|
||||
|
||||
/**
|
||||
* The type of the event. It should be namespaced similar to the
|
||||
* Java package naming conventions,
|
||||
* e.g. `com.example.subdomain.event.type`. It cannot be changed
|
||||
* after object initialization.
|
||||
*/
|
||||
public string? event_type { get; construct; default = null; }
|
||||
public string? event_type {
|
||||
get {
|
||||
return _event_type;
|
||||
}
|
||||
|
||||
construct {
|
||||
_event_type = value;
|
||||
}
|
||||
|
||||
default = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The event as a JSON node.
|
||||
|
@ -19,15 +19,111 @@
|
||||
/**
|
||||
* Class for representing a room membership events
|
||||
*
|
||||
* The room membership event class.
|
||||
* Adjusts the membership state for a user in a room. It is preferable
|
||||
* to use the membership APIs (`/rooms/<room id>/invite` etc) when
|
||||
* performing membership actions rather than adjusting the state
|
||||
* directly as there are a restricted set of valid
|
||||
* transformations. For example, user A cannot force user B to join a
|
||||
* room, and trying to force this state change directly will
|
||||
* fail.
|
||||
*
|
||||
* The following membership states are specified:
|
||||
*
|
||||
* - invite - The user has been invited to join a room, but has not
|
||||
* yet joined it. They may not participate in the room until they
|
||||
* join.
|
||||
*
|
||||
* - join - The user has joined the room (possibly after accepting an
|
||||
* invite), and may participate in it.
|
||||
*
|
||||
* - leave - The user was once joined to the room, but has since left
|
||||
* (possibly by choice, or possibly by being kicked).
|
||||
*
|
||||
* - ban - The user has been banned from the room, and is no longer
|
||||
* allowed to join it until they are un-banned from the room (by
|
||||
* having their membership state set to a value other than ban).
|
||||
*
|
||||
* - knock - This is a reserved word, which currently has no meaning.
|
||||
*
|
||||
* The third_party_invite property will be set if this invite is an
|
||||
* invite event and is the successor of an m.room.third_party_invite
|
||||
* event, and absent otherwise.
|
||||
*
|
||||
* This event may also include an invite_room_state key outside the
|
||||
* content key. If present, this contains an array of stripped state
|
||||
* events. These events provide information on a few select state
|
||||
* events such as the room name.
|
||||
*/
|
||||
public class Matrix.Event.RoomMember : Matrix.Event.State {
|
||||
private List<Matrix.Event.State>? _invite_room_state = null;
|
||||
|
||||
/**
|
||||
* The membership state of the user.
|
||||
*/
|
||||
public RoomMembership membership {
|
||||
get; set;
|
||||
get;
|
||||
|
||||
set;
|
||||
|
||||
default = RoomMembership.UNKNOWN;
|
||||
}
|
||||
public string? avatar_url { get; set; }
|
||||
public string? display_name { get; set; }
|
||||
|
||||
/**
|
||||
* The avatar URL for this user, if any. This is added by the
|
||||
* homeserver.
|
||||
*/
|
||||
public string? avatar_url { get; set; default = null; }
|
||||
|
||||
/**
|
||||
* The display name for this user, if any. This is added by the
|
||||
* homeserver.
|
||||
*/
|
||||
public string? display_name { get; set; default = null; }
|
||||
|
||||
/**
|
||||
* A name which can be displayed to represent the user instead of
|
||||
* their third party identifier
|
||||
*/
|
||||
public string? tpi_display_name { get; set; default = null; }
|
||||
|
||||
/**
|
||||
* The invited matrix user ID. Must be equal to the user_id
|
||||
* property of the event.
|
||||
*/
|
||||
public string? tpi_signed_mxid { get; set; default = null; }
|
||||
|
||||
/**
|
||||
* The token property of the containing third_party_invite object.
|
||||
*/
|
||||
public string? tpi_signed_token { get; set; default = null; }
|
||||
|
||||
/**
|
||||
* A single signature from the verifying server, in the format
|
||||
* specified by the Signing Events section of the server-server
|
||||
* API.
|
||||
*/
|
||||
public Json.Node? tpi_signature { get; set; default = null; }
|
||||
|
||||
/**
|
||||
* A subset of the state of the room at the time of the invite, if
|
||||
* membership is invite.
|
||||
*/
|
||||
public List<Matrix.Event.State>? invite_room_state {
|
||||
get {
|
||||
return _invite_room_state;
|
||||
}
|
||||
|
||||
set {
|
||||
_invite_room_state = value.copy();
|
||||
}
|
||||
|
||||
default = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The user ID whom this event relates to.
|
||||
*/
|
||||
public string? user_id { get; set; default = null; }
|
||||
|
||||
protected override void
|
||||
from_json(Json.Node json_data)
|
||||
@ -37,6 +133,14 @@ public class Matrix.Event.RoomMember : Matrix.Event.State {
|
||||
Json.Object content_root = root.get_member("content").get_object();
|
||||
Json.Node? node;
|
||||
|
||||
// Even though the state_key is handled by the parent class,
|
||||
// in this event type this actually means the sender
|
||||
if ((node = root.get_member("state_key")) != null) {
|
||||
_user_id = node.get_string();
|
||||
} else {
|
||||
warning("state_key (thus, a user ID) is missing from a m.room.member event");
|
||||
}
|
||||
|
||||
if ((node = content_root.get_member("membership")) != null) {
|
||||
Matrix.RoomMembership? mship = (Matrix.RoomMembership?)_g_enum_nick_to_value(
|
||||
typeof(Matrix.RoomMembership),
|
||||
@ -57,6 +161,57 @@ public class Matrix.Event.RoomMember : Matrix.Event.State {
|
||||
_display_name = node.get_string();
|
||||
}
|
||||
|
||||
if ((node = content_root.get_member("third_party_invite")) != null) {
|
||||
var tpi_root = node.get_object();
|
||||
|
||||
if ((node = tpi_root.get_member("display_name")) != null) {
|
||||
_tpi_display_name = node.get_string();
|
||||
} else {
|
||||
warning("content.third_party_invite.display_name is missing from a m.room.member event");
|
||||
}
|
||||
|
||||
if ((node = tpi_root.get_member("signed")) != null) {
|
||||
var signed_root = node.get_object();
|
||||
|
||||
if ((node = signed_root.get_member("mxid")) != null) {
|
||||
tpi_signed_mxid = node.get_string();
|
||||
} else {
|
||||
warning("content.third_party_invit.signed.mxid is missing from a m.room.member event");
|
||||
}
|
||||
|
||||
if ((node = signed_root.get_member("token")) != null) {
|
||||
tpi_signed_token = node.get_string();
|
||||
} else {
|
||||
warning("content.third_party_invite.signed.token is missing from a m.room.member event");
|
||||
}
|
||||
|
||||
if ((node = signed_root.get_member("signatures")) != null) {
|
||||
tpi_signature = node;
|
||||
} else {
|
||||
warning("content.third_party_invite.signed.signatures is missing from a m.room.member event");
|
||||
}
|
||||
} else {
|
||||
warning("content.third_party_invite.signed is missing from a m.room.member event");
|
||||
}
|
||||
}
|
||||
|
||||
if ((node = root.get_member("invite_room_state")) != null) {
|
||||
var events = node.get_array();
|
||||
|
||||
if (events.get_length() > 0) {
|
||||
_invite_room_state = null;
|
||||
|
||||
events.foreach_element((ary, idx, member_node) => {
|
||||
try {
|
||||
var evt = Matrix.Event.Base.new_from_json(
|
||||
null, member_node);
|
||||
|
||||
_invite_room_state.prepend((Matrix.Event.State)evt);
|
||||
} catch (GLib.Error e) {}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Chain up
|
||||
base.from_json(json_data);
|
||||
}
|
||||
@ -68,19 +223,21 @@ public class Matrix.Event.RoomMember : Matrix.Event.State {
|
||||
Json.Object root, content_root;
|
||||
string? mship;
|
||||
|
||||
if (membership == RoomMembership.UNKNOWN) {
|
||||
throw new Matrix.Error.UNKNOWN_VALUE(
|
||||
"Unknown membership value cannot be added to a room member event");
|
||||
}
|
||||
|
||||
root = json_data.get_object();
|
||||
|
||||
content_root = _json_object_node_ensure_field(json_data,
|
||||
"content",
|
||||
Json.NodeType.OBJECT)
|
||||
.get_object();
|
||||
|
||||
root.set_string_member("state_key", state_key);
|
||||
// I’m not sure if it is a good idea to set it here.
|
||||
if (user_id != null) {
|
||||
root.set_string_member("state_key", user_id);
|
||||
}
|
||||
|
||||
if (membership == RoomMembership.UNKNOWN) {
|
||||
throw new Matrix.Error.UNKNOWN_VALUE(
|
||||
"Unknown membership value cannot be added to a room member event");
|
||||
}
|
||||
|
||||
mship = _g_enum_value_to_nick(typeof(Matrix.RoomMembership),
|
||||
membership);
|
||||
@ -97,6 +254,65 @@ public class Matrix.Event.RoomMember : Matrix.Event.State {
|
||||
content_root.set_string_member("displayname", display_name);
|
||||
}
|
||||
|
||||
var tpi_root = new Json.Object();
|
||||
|
||||
if (_tpi_display_name != null) {
|
||||
tpi_root.set_string_member("display_name", tpi_display_name);
|
||||
}
|
||||
|
||||
var tpi_signed_root = new Json.Object();
|
||||
|
||||
if (_tpi_signed_mxid != null) {
|
||||
tpi_signed_root.set_string_member("mxid", tpi_signed_mxid);
|
||||
}
|
||||
|
||||
if (_tpi_signed_token != null) {
|
||||
tpi_signed_root.set_string_member("token", tpi_signed_token);
|
||||
}
|
||||
|
||||
if (_tpi_signature != null) {
|
||||
tpi_signed_root.set_member("signature", tpi_signature);
|
||||
}
|
||||
|
||||
if ((tpi_signed_root.get_size() != 3)
|
||||
&& (tpi_signed_root.get_size() != 0)) {
|
||||
warning("3rd party invite data is not filled; ignoring");
|
||||
|
||||
tpi_signed_root = null;
|
||||
}
|
||||
|
||||
if ((_tpi_display_name != null) && (tpi_signed_root.get_size() == 3)) {
|
||||
var tpi_signed_node = new Json.Node(Json.NodeType.OBJECT);
|
||||
tpi_signed_node.set_object(tpi_signed_root);
|
||||
tpi_root.set_member("signed", tpi_signed_node);
|
||||
}
|
||||
|
||||
if (tpi_root.get_size() == 2) {
|
||||
var tpi_node = new Json.Node(Json.NodeType.OBJECT);
|
||||
tpi_node.set_object(tpi_root);
|
||||
content_root.set_member("third_party_invite", tpi_node);
|
||||
} else if (tpi_root.get_size() != 0) {
|
||||
warning("3rd party invite data is incomplete; ignoring");
|
||||
}
|
||||
|
||||
if (_invite_room_state != null) {
|
||||
var state_ary = new Json.Array();
|
||||
|
||||
foreach (var entry in _invite_room_state) {
|
||||
var state_node = entry.get_stripped_node();
|
||||
|
||||
if (state_node != null) {
|
||||
state_ary.add_element(state_node);
|
||||
}
|
||||
}
|
||||
|
||||
if (state_ary.get_length() > 0) {
|
||||
var state_node = new Json.Node(Json.NodeType.ARRAY);
|
||||
state_node.set_array(state_ary);
|
||||
root.set_member("invite_room_state", state_node);
|
||||
}
|
||||
}
|
||||
|
||||
base.to_json(json_data);
|
||||
}
|
||||
}
|
||||
|
@ -63,9 +63,8 @@ cb_room_member_event(MatrixClient *client,
|
||||
MatrixEventBase *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_printerr("Incoming room member event from %s in room %s (%s)\n",
|
||||
matrix_event_room_get_sender(MATRIX_EVENT_ROOM(event)),
|
||||
matrix_event_room_get_room_id(MATRIX_EVENT_ROOM(event)),
|
||||
g_printerr("Incoming room member event from %s via room %s\n",
|
||||
matrix_event_room_member_get_user_id(MATRIX_EVENT_ROOM_MEMBER(event)),
|
||||
room_id);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user