-
Notifications
You must be signed in to change notification settings - Fork 403
Expand file tree
/
Copy pathSessionHandler.cs
More file actions
130 lines (111 loc) · 4.26 KB
/
SessionHandler.cs
File metadata and controls
130 lines (111 loc) · 4.26 KB
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
using StableSwarmUI.Utils;
using StableSwarmUI.Core;
using System.Collections.Concurrent;
using LiteDB;
using StableSwarmUI.Text2Image;
using FreneticUtilities.FreneticToolkit;
using FreneticUtilities.FreneticExtensions;
namespace StableSwarmUI.Accounts;
/// <summary>Core manager for sessions.</summary>
public class SessionHandler
{
/// <summary>How long the random session ID tokens should be.</summary>
public int SessionIDLength = 40; // TODO: Configurable
/// <summary>Map of currently tracked sessions by ID.</summary>
public ConcurrentDictionary<string, Session> Sessions = new();
/// <summary>Temporary map of current users. Do not use this directly, use <see cref="GetUser(string)"/>.</summary>
public ConcurrentDictionary<string, User> Users = new();
/// <summary>ID to use for the local user when in single-user mode.</summary>
public static string LocalUserID = "local";
/// <summary>Internal database.</summary>
public ILiteDatabase Database;
/// <summary>Internal database (users).</summary>
public ILiteCollection<User.DatabaseEntry> UserDatabase;
/// <summary>Internal database (presets).</summary>
public ILiteCollection<T2IPreset> T2IPresets;
/// <summary>Generic user data store.</summary>
public ILiteCollection<GenericDataStore> GenericData;
/// <summary>Internal database access locker.</summary>
public LockObject DBLock = new();
public User GenericSharedUser;
/// <summary>Helper for the database to store generic datablob.s</summary>
public class GenericDataStore
{
[BsonId]
public string ID { get; set; }
public string Data { get; set; }
}
public SessionHandler()
{
Database = new LiteDatabase($"{Program.DataDir}/Users.ldb");
UserDatabase = Database.GetCollection<User.DatabaseEntry>("users");
T2IPresets = Database.GetCollection<T2IPreset>("t2i_presets");
GenericData = Database.GetCollection<GenericDataStore>("generic_data");
GenericSharedUser = GetUser("__shared");
}
public Session CreateAdminSession(string source, string userId = null)
{
if (HasShutdown)
{
throw new InvalidOperationException("Session handler is shutting down.");
}
userId ??= LocalUserID;
User user = GetUser(userId);
user.Restrictions.Admin = true;
Logs.Info($"Creating new admin session '{userId}' for {source}");
for (int i = 0; i < 1000; i++)
{
Session sess = new()
{
ID = Utilities.SecureRandomHex(SessionIDLength),
OriginAddress = source,
User = user
};
if (Sessions.TryAdd(sess.ID, sess))
{
sess.User.CurrentSessions[sess.ID] = sess;
return sess;
}
}
throw new InvalidOperationException("Something is critically wrong in the session handler, cannot generate unique IDs!");
}
/// <summary>Gets or creates the user for the given ID.</summary>
public User GetUser(string userId)
{
userId = Utilities.StrictFilenameClean(userId).Replace("/", "");
if (userId.Length == 0)
{
userId = "_";
}
return Users.GetOrCreate(userId, () =>
{
User.DatabaseEntry userData = UserDatabase.FindById(userId);
userData ??= new() { ID = userId, RawSettings = "\n" };
return new(this, userData);
});
}
/// <summary>Tries to get the session for an id.</summary>
/// <returns><see cref="true"/> if found, otherwise <see cref="false"/>.</returns>
public bool TryGetSession(string id, out Session session)
{
return Sessions.TryGetValue(id, out session);
}
private volatile bool HasShutdown;
/// <summary>Main shutdown handler, triggered by <see cref="Program.Shutdown"/>.</summary>
public void Shutdown()
{
if (HasShutdown)
{
return;
}
HasShutdown = true;
Logs.Info("Will shut down session handler...");
lock (DBLock)
{
Sessions.Clear();
Logs.Info("Will save user data.");
Database.Dispose();
}
Logs.Info("Session handler is shut down.");
}
}