about summary refs log tree commit diff
path: root/Tests/LibMatrix.HomeserverEmulator/Services/UserStore.cs
diff options
context:
space:
mode:
authorEmma [it/its]@Rory& <root@rory.gay>2024-04-05 18:58:32 +0200
committerEmma [it/its]@Rory& <root@rory.gay>2024-04-05 18:58:32 +0200
commit37b97d65c0a5262539a5de560e911048166b8bba (patch)
treef704a9c703b0ec47122a460576e151e0cb06fdc6 /Tests/LibMatrix.HomeserverEmulator/Services/UserStore.cs
parentFix merge conficts between machines (diff)
downloadLibMatrix-37b97d65c0a5262539a5de560e911048166b8bba.tar.xz
Fix homeserver resolution, rewrite homeserver initialisation, HSE work
Diffstat (limited to 'Tests/LibMatrix.HomeserverEmulator/Services/UserStore.cs')
-rw-r--r--Tests/LibMatrix.HomeserverEmulator/Services/UserStore.cs60
1 files changed, 52 insertions, 8 deletions
diff --git a/Tests/LibMatrix.HomeserverEmulator/Services/UserStore.cs b/Tests/LibMatrix.HomeserverEmulator/Services/UserStore.cs
index 4f238a0..4ce9f92 100644
--- a/Tests/LibMatrix.HomeserverEmulator/Services/UserStore.cs
+++ b/Tests/LibMatrix.HomeserverEmulator/Services/UserStore.cs
@@ -18,11 +18,15 @@ public class UserStore {
     public UserStore(HSEConfiguration config, RoomStore roomStore) {
         _roomStore = roomStore;
         if (config.StoreData) {
-            var path = Path.Combine(config.DataStoragePath, "users");
-            if (!Directory.Exists(path)) Directory.CreateDirectory(path);
-            foreach (var file in Directory.GetFiles(path)) {
-                var user = JsonSerializer.Deserialize<User>(File.ReadAllText(file));
-                if (user is not null) _users.Add(user);
+            var dataDir = Path.Combine(HSEConfiguration.Current.DataStoragePath, "users");
+            if (!Directory.Exists(dataDir)) Directory.CreateDirectory(dataDir);
+            foreach (var userId in Directory.GetDirectories(dataDir)) {
+                var tokensDir = Path.Combine(dataDir, userId, "tokens.json");
+                var path = Path.Combine(dataDir, userId, $"user.json");
+
+                var user = JsonSerializer.Deserialize<User>(File.ReadAllText(path));
+                user!.AccessTokens = JsonSerializer.Deserialize<ObservableDictionary<string, User.SessionInfo>>(File.ReadAllText(tokensDir))!;
+                _users.Add(user);
             }
 
             Console.WriteLine($"Loaded {_users.Count} users from disk");
@@ -42,7 +46,7 @@ public class UserStore {
         return await CreateUser(userId);
     }
 
-    public async Task<User?> GetUserByToken(string token, bool createIfNotExists = false, string? serverName = null) {
+    public async Task<User?> GetUserByTokenOrNull(string token, bool createIfNotExists = false, string? serverName = null) {
         if (_users.Any(x => x.AccessTokens.ContainsKey(token)))
             return _users.First(x => x.AccessTokens.ContainsKey(token));
 
@@ -53,6 +57,13 @@ public class UserStore {
         return await CreateUser(uid);
     }
 
+    public async Task<User> GetUserByToken(string token, bool createIfNotExists = false, string? serverName = null) {
+        return await GetUserByTokenOrNull(token, createIfNotExists, serverName) ?? throw new MatrixException() {
+            ErrorCode = MatrixException.ErrorCodes.M_UNKNOWN_TOKEN,
+            Error = "Invalid token."
+        };
+    }
+
     public async Task<User> CreateUser(string userId, Dictionary<string, object>? profile = null) {
         profile ??= new();
         if (!profile.ContainsKey("displayname")) profile.Add("displayname", userId.Split(":")[0]);
@@ -97,6 +108,7 @@ public class UserStore {
             Profile = new();
             AccountData = new();
             RoomKeys = new();
+            AuthorizedSessions = new();
         }
 
         private CancellationTokenSource _debounceCts = new();
@@ -106,6 +118,7 @@ public class UserStore {
         private ObservableDictionary<string, object> _profile;
         private ObservableCollection<StateEventResponse> _accountData;
         private ObservableDictionary<string, RoomKeysResponse> _roomKeys;
+        private ObservableDictionary<string, AuthorizedSession> _authorizedSessions;
 
         public string UserId {
             get => _userId;
@@ -162,15 +175,29 @@ public class UserStore {
             }
         }
 
+        public ObservableDictionary<string, AuthorizedSession> AuthorizedSessions {
+            get => _authorizedSessions;
+            set {
+                if (value == _authorizedSessions) return;
+                _authorizedSessions = new(value);
+                _authorizedSessions.CollectionChanged += async (sender, args) => await SaveDebounced();
+                OnPropertyChanged();
+            }
+        }
+
         public async Task SaveDebounced() {
             if (!HSEConfiguration.Current.StoreData) return;
-            _debounceCts.Cancel();
+            await _debounceCts.CancelAsync();
             _debounceCts = new CancellationTokenSource();
             try {
                 await Task.Delay(250, _debounceCts.Token);
-                var path = Path.Combine(HSEConfiguration.Current.DataStoragePath, "users", $"{_userId}.json");
+                var dataDir = Path.Combine(HSEConfiguration.Current.DataStoragePath, "users", _userId);
+                if (!Directory.Exists(dataDir)) Directory.CreateDirectory(dataDir);
+                var tokensDir = Path.Combine(dataDir, "tokens.json");
+                var path = Path.Combine(dataDir, $"user.json");
                 Console.WriteLine($"Saving user {_userId} to {path}!");
                 await File.WriteAllTextAsync(path, this.ToJson(ignoreNull: true));
+                await File.WriteAllTextAsync(tokensDir, AccessTokens.ToJson(ignoreNull: true));
             }
             catch (TaskCanceledException) { }
             catch (InvalidOperationException) { } // We don't care about 100% data safety, this usually happens when something is updated while serialising
@@ -187,7 +214,19 @@ public class UserStore {
 
                 public class SyncRoomPosition {
                     public int TimelinePosition { get; set; }
+                    public string LastTimelineEventId { get; set; }
                     public int AccountDataPosition { get; set; }
+                    public bool Joined { get; set; }
+                }
+
+                public UserSyncState Clone() {
+                    return new() {
+                        FilterId = FilterId,
+                        RoomPositions = RoomPositions.ToDictionary(x => x.Key, x => new SyncRoomPosition() {
+                            TimelinePosition = x.Value.TimelinePosition,
+                            AccountDataPosition = x.Value.AccountDataPosition
+                        })
+                    };
                 }
             }
         }
@@ -202,5 +241,10 @@ public class UserStore {
                 UserId = UserId
             };
         }
+
+        public class AuthorizedSession {
+            public string Homeserver { get; set; }
+            public string AccessToken { get; set; }
+        }
     }
 }
\ No newline at end of file