about summary refs log tree commit diff
path: root/Utilities/LibMatrix.HomeserverEmulator/Controllers/Rooms/RoomStateController.cs
blob: 74c70a3b48500d00b7b9f71957f3219ce878a317 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
using System.Collections.Frozen;
using System.Text.Json.Nodes;
using LibMatrix.HomeserverEmulator.Extensions;
using LibMatrix.HomeserverEmulator.Services;
using Microsoft.AspNetCore.Mvc;

namespace LibMatrix.HomeserverEmulator.Controllers.Rooms;

[ApiController]
[Route("/_matrix/client/{version}/rooms/{roomId}/state")]
public class RoomStateController(ILogger<RoomStateController> logger, TokenService tokenService, UserStore userStore, RoomStore roomStore) : ControllerBase {
    [HttpGet("")]
    public async Task<FrozenSet<StateEventResponse>> GetState(string roomId) {
        var token = tokenService.GetAccessTokenOrNull(HttpContext);
        if (token == null)
            throw new MatrixException() {
                ErrorCode = "M_MISSING_TOKEN",
                Error = "Missing token"
            };

        var user = await userStore.GetUserByToken(token);
        if (user == null)
            throw new MatrixException() {
                ErrorCode = "M_UNKNOWN_TOKEN",
                Error = "No such user"
            };

        var room = roomStore.GetRoomById(roomId);
        if (room == null)
            throw new MatrixException() {
                ErrorCode = "M_NOT_FOUND",
                Error = "Room not found"
            };

        return room.State;
    }

    [HttpGet("{eventType}")]
    public async Task<object?> GetState(string roomId, string eventType, [FromQuery] string format = "client") {
        return await GetState(roomId, eventType, "", format);
    }

    [HttpGet("{eventType}/{stateKey}")]
    public async Task<object?> GetState(string roomId, string eventType, string stateKey, [FromQuery] string format = "client") {
        var token = tokenService.GetAccessTokenOrNull(HttpContext);
        if (token == null)
            throw new MatrixException() {
                ErrorCode = "M_MISSING_TOKEN",
                Error = "Missing token"
            };

        var user = await userStore.GetUserByToken(token);
        if (user == null)
            throw new MatrixException() {
                ErrorCode = "M_UNKNOWN_TOKEN",
                Error = "No such user"
            };

        var room = roomStore.GetRoomById(roomId);
        if (room == null)
            throw new MatrixException() {
                ErrorCode = "M_NOT_FOUND",
                Error = "Room not found"
            };

        var stateEvent = room.State.FirstOrDefault(x => x.Type == eventType && x.StateKey == stateKey);
        if (stateEvent == null) {
            Console.WriteLine($"Event not found in room {roomId} matching {eventType}/{stateKey}");
            throw new MatrixException() {
                ErrorCode = "M_NOT_FOUND",
                Error = "Event not found"
            };
        }

        // return stateEvent;
        return format == "event" ? stateEvent : stateEvent.RawContent;
    }

    [HttpPut("{eventType}")]
    public async Task<EventIdResponse> SetState(string roomId, string eventType, [FromBody] JsonObject? request) {
        return await SetState(roomId, eventType, "", request);
    }

    [HttpPut("{eventType}/{stateKey}")]
    public async Task<EventIdResponse> SetState(string roomId, string eventType, string stateKey, [FromBody] JsonObject? request) {
        var token = tokenService.GetAccessTokenOrNull(HttpContext);
        if (token == null)
            throw new MatrixException() {
                ErrorCode = "M_MISSING_TOKEN",
                Error = "Missing token"
            };

        var user = await userStore.GetUserByToken(token);
        if (user == null)
            throw new MatrixException() {
                ErrorCode = "M_UNKNOWN_TOKEN",
                Error = "No such user"
            };

        var room = roomStore.GetRoomById(roomId);
        if (room == null)
            throw new MatrixException() {
                ErrorCode = "M_NOT_FOUND",
                Error = "Room not found"
            };
        var evt = room.SetStateInternal(new StateEvent() { Type = eventType, StateKey = stateKey, RawContent = request }.ToStateEvent(user, room));
        evt.Type = eventType;
        evt.StateKey = stateKey;
        return new EventIdResponse() {
            EventId = evt.EventId ?? throw new InvalidOperationException("EventId is null")
        };
    }
}