From 37b97d65c0a5262539a5de560e911048166b8bba Mon Sep 17 00:00:00 2001 From: "Emma [it/its]@Rory&" Date: Fri, 5 Apr 2024 18:58:32 +0200 Subject: Fix homeserver resolution, rewrite homeserver initialisation, HSE work --- .../Services/UserStore.cs | 60 +++++++++++++++++++--- 1 file changed, 52 insertions(+), 8 deletions(-) (limited to 'Tests/LibMatrix.HomeserverEmulator/Services/UserStore.cs') 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(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(File.ReadAllText(path)); + user!.AccessTokens = JsonSerializer.Deserialize>(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 GetUserByToken(string token, bool createIfNotExists = false, string? serverName = null) { + public async Task 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 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 CreateUser(string userId, Dictionary? 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 _profile; private ObservableCollection _accountData; private ObservableDictionary _roomKeys; + private ObservableDictionary _authorizedSessions; public string UserId { get => _userId; @@ -162,15 +175,29 @@ public class UserStore { } } + public ObservableDictionary 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 -- cgit 1.4.1