Fix Matrix.Event.RoomMember
It now complies with the Matrix spec.
This commit is contained in:
		| @@ -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,24 +223,26 @@ 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); | ||||
|  | ||||
|        if (mship != null) { | ||||
|         if (mship != null) { | ||||
|             content_root.set_string_member("membership", mship); | ||||
|         } | ||||
|  | ||||
| @@ -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); | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user